From 528fc0a026beb201ae71787a4e402daf98cb59f5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 10 Dec 2015 16:08:46 +0100 Subject: [PATCH 001/121] Started vcard interface for belcard --- configure.ac | 36 +++++++++++++++++++++++++++++++++++- coreapi/Makefile.am | 5 ++++- coreapi/friend.c | 13 +++++++++++++ coreapi/linphonecore.h | 2 -- coreapi/linphonefriend.h | 11 +++++++++++ coreapi/private.h | 1 + coreapi/vcard.cc | 27 +++++++++++++++++++++++++++ coreapi/vcard.h | 21 +++++++++++++++++++++ 8 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 coreapi/vcard.cc create mode 100644 coreapi/vcard.h diff --git a/configure.ac b/configure.ac index eb9f974cc..7f2b95aad 100644 --- a/configure.ac +++ b/configure.ac @@ -877,6 +877,39 @@ if test x$enable_tunnel = xtrue; then AC_DEFINE(TUNNEL_ENABLED,1,[Tells tunnel extension is built-in]) fi +AC_ARG_ENABLE(vcard, + [AS_HELP_STRING([--enable-vcard=[yes/no]], [Turn on compilation of vcard (default=auto)])], + [case "${enableval}" in + yes) enable_vcard=true ;; + no) enable_vcard=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-vcard) ;; + esac], + [enable_vcard=auto] +) + +if test x$enable_vcard != xfalse; then + PKG_CHECK_MODULES(BELCARD, belcard, [found_vcard=yes],[found_vcard=no]) + if test "$found_vcard" = "no"; then + dnl Check the lib presence in case the PKG-CONFIG version is not found + AC_LANG_CPLUSPLUS + AC_CHECK_LIB(belcard, main, [BELCARD_LIBS+=" -lbelr -lbelcard"; found_vcard=yes], [foo=bar]) + AC_LANG_C + fi + if test "$found_vcard" = "yes"; then + enable_vcard=true + else + if test x$enable_vcard = xtrue; then + AC_MSG_ERROR([belcard, required for vcard support, not found]) + fi + enable_vcard=false + fi + + AC_SUBST(BELCARD_CFLAGS) + AC_SUBST(BELCARD_LIBS) +fi + +AM_CONDITIONAL(BUILD_VCARD, test x$enable_vcard = xtrue) + AC_ARG_ENABLE(msg-storage, [AS_HELP_STRING([--enable-msg-storage=[yes/no]], [Turn on compilation of message storage (default=auto)])], [case "${enableval}" in @@ -1105,7 +1138,8 @@ printf "* %-30s %s\n" "Account assistant" $build_wizard printf "* %-30s %s\n" "Console interface" $console_ui printf "* %-30s %s\n" "Tools" $build_tools printf "* %-30s %s\n" "Message storage" $enable_msg_storage -printf "* %-30s %s\n" "Call logs storage" $enable_call_logs_storage +printf "* %-30s %s\n" "Call logs storage" $enable_call_logs_storage +printf "* %-30s %s\n" "VCard support" $enable_vcard printf "* %-30s %s\n" "IM encryption" $lime printf "* %-30s %s\n" "uPnP support" $build_upnp printf "* %-30s %s\n" "LDAP support" $enable_ldap diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 02c7f442d..6d9a1c179 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -114,7 +114,8 @@ else liblinphone_la_SOURCES+=linphone_tunnel_stubs.c linphone_tunnel.h endif - +liblinphone_la_SOURCES+=vcard.cc vcard.h +liblinphone_la_CXXFLAGS=-std=c++11 liblinphone_la_LDFLAGS= -version-info $(LIBLINPHONE_SO_VERSION) -no-undefined @@ -142,6 +143,7 @@ liblinphone_la_LIBADD= \ $(LIBXML2_LIBS) \ $(LDAP_LIBS) \ $(SASL_LIBS) \ + $(BELCARD_LIBS) \ $(ZLIB_LIBS) @@ -164,6 +166,7 @@ COMMON_CFLAGS=\ $(LIBXML2_CFLAGS) \ $(LDAP_CFLAGS) \ $(SASL_CFLAGS) \ + $(BELCARD_CFLAGS) \ $(ZLIB_CFLAGS) if BUILD_WIZARD diff --git a/coreapi/friend.c b/coreapi/friend.c index 487cfd2a4..a3334b703 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -132,6 +132,7 @@ LinphoneFriend * linphone_friend_new(){ obj->pol=LinphoneSPAccept; obj->presence=NULL; obj->subscribe=TRUE; + obj->vcard = NULL; return obj; } @@ -290,6 +291,7 @@ static void _linphone_friend_destroy(LinphoneFriend *lf){ if (lf->presence != NULL) linphone_presence_model_unref(lf->presence); if (lf->uri!=NULL) linphone_address_destroy(lf->uri); if (lf->info!=NULL) buddy_info_free(lf->info); + if (lf->vcard != NULL) linphone_vcard_free(lf->vcard); } static belle_sip_error_code _linphone_friend_marshall(belle_sip_object_t *obj, char* buff, size_t buff_size, size_t *offset) { @@ -726,6 +728,17 @@ void linphone_friend_destroy(LinphoneFriend *lf) { linphone_friend_unref(lf); } +LinphoneVCard* linphone_friend_get_vcard(LinphoneFriend *fr) { + return fr->vcard; +} + +void linphone_friend_set_vcard(LinphoneFriend *fr, LinphoneVCard *vcard) { + if (fr->vcard) { + linphone_vcard_free(fr->vcard); + } + fr->vcard = vcard; +} + BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriend); BELLE_SIP_INSTANCIATE_VPTR(LinphoneFriend, belle_sip_object_t, diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 6d6444f03..d31a23204 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -4232,7 +4232,6 @@ LINPHONE_PUBLIC const char* linphone_transport_to_string(LinphoneTransportType t **/ LINPHONE_PUBLIC LinphoneTransportType linphone_transport_parse(const char* transport); - /** * @ingroup media_parameters * Get default call parameters reflecting current linphone core configuration @@ -4242,7 +4241,6 @@ LINPHONE_PUBLIC LinphoneTransportType linphone_transport_parse(const char* trans */ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *lc); - #ifdef __cplusplus } #endif diff --git a/coreapi/linphonefriend.h b/coreapi/linphonefriend.h index 1a6535fed..2276c98bb 100644 --- a/coreapi/linphonefriend.h +++ b/coreapi/linphonefriend.h @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define LINPHONEFRIEND_H_ #include "linphonepresence.h" +#include "vcard.h" #ifdef __cplusplus extern "C" { @@ -411,6 +412,16 @@ LINPHONE_PUBLIC void linphone_friend_unref(LinphoneFriend *lf); * Returns the LinphoneCore object managing this friend, if any. */ LINPHONE_PUBLIC LinphoneCore *linphone_friend_get_core(const LinphoneFriend *fr); + +/** + * Returns the VCard object associated to this friend, if any + */ +LINPHONE_PUBLIC LinphoneVCard* linphone_friend_get_vcard(LinphoneFriend *fr); + +/** + * Returns the VCard object associated to this friend, if any + */ +LINPHONE_PUBLIC void linphone_friend_set_vcard(LinphoneFriend *fr, LinphoneVCard *vcard); /** * @} */ diff --git a/coreapi/private.h b/coreapi/private.h index 797b19708..2190af8e3 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -653,6 +653,7 @@ struct _LinphoneFriend{ bool_t inc_subscribe_pending; bool_t commit; bool_t initial_subscribes_sent; /*used to know if initial subscribe message was sent or not*/ + LinphoneVCard *vcard; }; BELLE_SIP_DECLARE_VPTR(LinphoneFriend); diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc new file mode 100644 index 000000000..88d77178f --- /dev/null +++ b/coreapi/vcard.cc @@ -0,0 +1,27 @@ +#include "vcard.h" +#include "belcard/belcard.hpp" + +struct _LinphoneVCard { + shared_ptr belcard; +}; + +extern "C" LinphoneVCard* linphone_vcard_new(void) { + LinphoneVCard* vcard = (LinphoneVCard*) malloc(sizeof(LinphoneVCard)); + vcard->belcard = belcard::BelCardGeneric::create(); + return vcard; +} + +extern "C" void linphone_vcard_free(LinphoneVCard *vcard) { + vcard->belcard.reset(); + free(vcard); +} + +extern "C" void linphone_vcard_set_full_name(LinphoneVCard *vcard, const char *name) { + shared_ptr fn = belcard::BelCardGeneric::create(); + fn->setValue(name); + vcard->belcard->setFullName(fn); +} + +extern "C" const char* linphone_vcard_get_full_name(LinphoneVCard *vcard) { + return vcard->belcard->getFullName() ? vcard->belcard->getFullName()->getValue().c_str() : NULL; +} \ No newline at end of file diff --git a/coreapi/vcard.h b/coreapi/vcard.h new file mode 100644 index 000000000..93bb17d30 --- /dev/null +++ b/coreapi/vcard.h @@ -0,0 +1,21 @@ +#ifndef LINPHONE_VCARD_H +#define LINPHONE_VCARD_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct _LinphoneVCard LinphoneVCard; + +LinphoneVCard* linphone_vcard_new(void); +void linphone_vcard_free(LinphoneVCard *vcard); + +void linphone_vcard_set_full_name(LinphoneVCard *vcard, const char *name); +const char* linphone_vcard_get_full_name(LinphoneVCard *vcard); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file From 6703bd2079f2fb205e88cfde57731663ccebe9df Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 14 Dec 2015 11:28:12 +0100 Subject: [PATCH 002/121] Started to integrate vcards with gtk ui --- coreapi/friend.c | 53 ++++++++++++++++++++++++++++++++++++++-- coreapi/linphonefriend.h | 16 ++++++++++-- coreapi/vcard.cc | 26 +++++++++++++++++--- coreapi/vcard.h | 33 ++++++++++++++++++++++--- gtk/friendlist.c | 18 ++++++++++---- 5 files changed, 130 insertions(+), 16 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index a3334b703..6001c1a47 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -207,12 +207,23 @@ int linphone_friend_set_address(LinphoneFriend *lf, const LinphoneAddress *addr) } int linphone_friend_set_name(LinphoneFriend *lf, const char *name){ - LinphoneAddress *fr=lf->uri; - if (fr==NULL){ + LinphoneAddress *fr = lf->uri; + LinphoneVCard *vcard = NULL; + + if (fr == NULL){ ms_error("linphone_friend_set_sip_addr() must be called before linphone_friend_set_name()."); return -1; } linphone_address_set_display_name(fr,name); + + + vcard = linphone_friend_get_vcard(lf); + if (!vcard) { + linphone_friend_create_vcard(lf, name); + } else { + linphone_vcard_set_full_name(vcard, name); + } + return 0; } @@ -739,6 +750,44 @@ void linphone_friend_set_vcard(LinphoneFriend *fr, LinphoneVCard *vcard) { fr->vcard = vcard; } +bool_t linphone_friend_create_vcard(LinphoneFriend *fr, const char *name) { + LinphoneVCard *vcard = NULL; + const char *fullName = NULL; + LinphoneAddress *addr = NULL; + + if (!fr || fr->vcard) { + ms_error("Friend is either null or already has a vcard"); + return FALSE; + } + + addr = fr->uri; + if (!addr && !name) { + ms_error("friend doesn't have an URI and name parameter is null"); + return FALSE; + } + + if (name) { + fullName = name; + } else { + const char *displayName = linphone_address_get_display_name(addr); + if (!displayName) { + ms_error("Friend's URI doesn't have a display name"); + return FALSE; + } + fullName = displayName; + } + + if (!fullName) { + ms_error("Couldn't determine the name to use for the vCard"); + return FALSE; + } + + vcard = linphone_vcard_new(); + linphone_vcard_set_full_name(vcard, fullName); + fr->vcard = vcard; + return TRUE; +} + BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriend); BELLE_SIP_INSTANCIATE_VPTR(LinphoneFriend, belle_sip_object_t, diff --git a/coreapi/linphonefriend.h b/coreapi/linphonefriend.h index 2276c98bb..ed3aa2b3a 100644 --- a/coreapi/linphonefriend.h +++ b/coreapi/linphonefriend.h @@ -404,24 +404,36 @@ LINPHONE_PUBLIC LinphoneFriend * linphone_friend_ref(LinphoneFriend *lf); /** * Release a reference to the linphone friend. - * @param[in] lf LinohoneFriend object + * @param[in] lf LinphoneFriend object **/ LINPHONE_PUBLIC void linphone_friend_unref(LinphoneFriend *lf); /** * Returns the LinphoneCore object managing this friend, if any. + * @param[in] fr LinphoneFriend object */ LINPHONE_PUBLIC LinphoneCore *linphone_friend_get_core(const LinphoneFriend *fr); /** * Returns the VCard object associated to this friend, if any + * @param[in] fr LinphoneFriend object */ LINPHONE_PUBLIC LinphoneVCard* linphone_friend_get_vcard(LinphoneFriend *fr); /** - * Returns the VCard object associated to this friend, if any + * Binds a VCard object to a friend + * @param[in] fr LinphoneFriend object + * @param[in] vcard The VCard object to bind */ LINPHONE_PUBLIC void linphone_friend_set_vcard(LinphoneFriend *fr, LinphoneVCard *vcard); + +/** + * Creates a VCard object associated to this friend if there isn't one yet and if the full name is available, either by the parameter or the one in the friend's SIP URI + * @param[in] fr LinphoneFriend object + * @param[in] name The full name of the friend or NULL to use the one from the friend's SIP URI + * @return true if the vCard has been created, false if it wasn't possible (for exemple if name and the friend's SIP URI are null or if the friend's SIP URI doesn't have a display name), or if there is already one vcard + */ +LINPHONE_PUBLIC bool_t linphone_friend_create_vcard(LinphoneFriend *fr, const char *name); /** * @} */ diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 88d77178f..343f9063b 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -1,3 +1,22 @@ +/* +vcard.cc +Copyright (C) 2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + #include "vcard.h" #include "belcard/belcard.hpp" @@ -6,14 +25,14 @@ struct _LinphoneVCard { }; extern "C" LinphoneVCard* linphone_vcard_new(void) { - LinphoneVCard* vcard = (LinphoneVCard*) malloc(sizeof(LinphoneVCard)); + LinphoneVCard* vcard = (LinphoneVCard*) ms_new0(LinphoneVCard, 1); vcard->belcard = belcard::BelCardGeneric::create(); return vcard; } extern "C" void linphone_vcard_free(LinphoneVCard *vcard) { vcard->belcard.reset(); - free(vcard); + ms_free(vcard); } extern "C" void linphone_vcard_set_full_name(LinphoneVCard *vcard, const char *name) { @@ -23,5 +42,6 @@ extern "C" void linphone_vcard_set_full_name(LinphoneVCard *vcard, const char *n } extern "C" const char* linphone_vcard_get_full_name(LinphoneVCard *vcard) { - return vcard->belcard->getFullName() ? vcard->belcard->getFullName()->getValue().c_str() : NULL; + const char *result = vcard->belcard->getFullName() ? vcard->belcard->getFullName()->getValue().c_str() : NULL; + return result; } \ No newline at end of file diff --git a/coreapi/vcard.h b/coreapi/vcard.h index 93bb17d30..7a2fbd42f 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -1,6 +1,31 @@ +/* +vcard.h +Copyright (C) 2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + #ifndef LINPHONE_VCARD_H #define LINPHONE_VCARD_H +#include + +#ifndef LINPHONE_PUBLIC +#define LINPHONE_PUBLIC MS2_PUBLIC +#endif + #ifdef __cplusplus extern "C" { @@ -8,11 +33,11 @@ extern "C" typedef struct _LinphoneVCard LinphoneVCard; -LinphoneVCard* linphone_vcard_new(void); -void linphone_vcard_free(LinphoneVCard *vcard); +LINPHONE_PUBLIC LinphoneVCard* linphone_vcard_new(void); +LINPHONE_PUBLIC void linphone_vcard_free(LinphoneVCard *vcard); -void linphone_vcard_set_full_name(LinphoneVCard *vcard, const char *name); -const char* linphone_vcard_get_full_name(LinphoneVCard *vcard); +LINPHONE_PUBLIC void linphone_vcard_set_full_name(LinphoneVCard *vcard, const char *name); +LINPHONE_PUBLIC const char* linphone_vcard_get_full_name(LinphoneVCard *vcard); #ifdef __cplusplus } diff --git a/gtk/friendlist.c b/gtk/friendlist.c index 41bc18ee1..271d220e4 100644 --- a/gtk/friendlist.c +++ b/gtk/friendlist.c @@ -716,19 +716,28 @@ void linphone_gtk_show_friends(void){ } void linphone_gtk_show_contact(LinphoneFriend *lf, GtkWidget *parent){ - GtkWidget *w=linphone_gtk_create_window("contact", parent); + GtkWidget *w = linphone_gtk_create_window("contact", parent); char *uri; const char *name; - const LinphoneAddress *f_uri=linphone_friend_get_address(lf); + const LinphoneAddress *f_uri = linphone_friend_get_address(lf); + LinphoneVCard *vcard = linphone_friend_get_vcard(lf); + + if (vcard) { + name = linphone_vcard_get_full_name(vcard); + } else { + name = linphone_address_get_display_name(f_uri); + } + uri=linphone_address_as_string_uri_only(f_uri); - name=linphone_address_get_display_name(f_uri); if (uri) { gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"sip_address")),uri); ms_free(uri); } + if (name){ gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"name")),name); } + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"show_presence")), linphone_friend_get_send_subscribe(lf)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"allow_presence")), @@ -772,9 +781,8 @@ void linphone_gtk_contact_ok(GtkWidget *button){ return ; } - linphone_address_set_display_name(friend_address,name); - linphone_friend_set_name(lf,name); linphone_friend_set_address(lf,friend_address); + linphone_friend_set_name(lf,name); linphone_friend_send_subscribe(lf,show_presence); linphone_friend_set_inc_subscribe_policy(lf,allow_presence==TRUE ? LinphoneSPAccept : LinphoneSPDeny); if (linphone_friend_in_list(lf)) { From 3782799e02cd25f0dfcb65759e77d3a74deb0b0f Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 14 Dec 2015 16:10:01 +0100 Subject: [PATCH 003/121] Added option in gtk ui to import contact(s) from vcard file --- coreapi/friend.c | 48 +++++++++++++++++++++++++++++++++++++++- coreapi/linphonefriend.h | 16 ++++++++++++++ coreapi/vcard.cc | 31 +++++++++++++++++++++++++- coreapi/vcard.h | 5 ++++- gtk/main.c | 15 +++++++++++++ gtk/main.ui | 15 +++++++++++++ 6 files changed, 127 insertions(+), 3 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index 6001c1a47..6ed7df80f 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -784,10 +784,56 @@ bool_t linphone_friend_create_vcard(LinphoneFriend *fr, const char *name) { vcard = linphone_vcard_new(); linphone_vcard_set_full_name(vcard, fullName); - fr->vcard = vcard; + linphone_friend_set_vcard(fr, vcard); return TRUE; } +LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard) { + LinphoneAddress* linphone_address = NULL; + LinphoneFriend *fr; + const char *name = NULL; + MSList *sipAddresses = NULL; + + if (vcard == NULL) { + ms_error("Cannot create friend from null vcard"); + return NULL; + } + name = linphone_vcard_get_full_name(vcard); + sipAddresses = linphone_vcard_get_sip_addresses(vcard); + + fr = linphone_friend_new(); + linphone_friend_set_vcard(fr, vcard); + + if (sipAddresses) { + const char *sipAddress = (const char *)sipAddresses->data; + linphone_address = linphone_address_new(sipAddress); + if (linphone_address) { + linphone_friend_set_address(fr, linphone_address); + linphone_address_destroy(linphone_address); + } + } + linphone_friend_set_name(fr, name); + + return fr; +} + +int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char *vcard_file) { + MSList *vcards = linphone_vcard_new_from_vcard4_file(vcard_file); + int count = 0; + + while (vcards != NULL && vcards->data != NULL) { + LinphoneVCard *vcard = (LinphoneVCard *)vcards->data; + LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); + if (lf) { + linphone_core_add_friend(lc, lf); + count++; + } + vcards = ms_list_next(vcards); + } + + return count; +} + BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriend); BELLE_SIP_INSTANCIATE_VPTR(LinphoneFriend, belle_sip_object_t, diff --git a/coreapi/linphonefriend.h b/coreapi/linphonefriend.h index ed3aa2b3a..3682546ff 100644 --- a/coreapi/linphonefriend.h +++ b/coreapi/linphonefriend.h @@ -434,6 +434,22 @@ LINPHONE_PUBLIC void linphone_friend_set_vcard(LinphoneFriend *fr, LinphoneVCard * @return true if the vCard has been created, false if it wasn't possible (for exemple if name and the friend's SIP URI are null or if the friend's SIP URI doesn't have a display name), or if there is already one vcard */ LINPHONE_PUBLIC bool_t linphone_friend_create_vcard(LinphoneFriend *fr, const char *name); + +/** + * Contructor same as linphone_friend_new() + linphone_friend_set_address() + * @param vcard a VCard object + * @return a new #LinphoneFriend with \link linphone_friend_get_vcard() vcard initialized \endlink + */ +LINPHONE_PUBLIC LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard); + +/** + * Creates and adds LinphoneFriend objects to LinphoneCore from a file that contains the vcard(s) to parse + * @param[in] lc the LinphoneCore object + * @param[in] vcard_file the path to a file that contains the vcard(s) to parse + * @return the amount of linphone friends created + */ +LINPHONE_PUBLIC int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char *vcard_file); + /** * @} */ diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 343f9063b..4d1a135b3 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "vcard.h" #include "belcard/belcard.hpp" +#include "belcard/belcard_parser.hpp" struct _LinphoneVCard { shared_ptr belcard; @@ -35,13 +36,41 @@ extern "C" void linphone_vcard_free(LinphoneVCard *vcard) { ms_free(vcard); } +extern "C" MSList* linphone_vcard_new_from_vcard4_file(const char *filename) { + MSList *result = NULL; + if (filename) { + if (ortp_file_exist(filename) == 0) { + belcard::BelCardParser *parser = new belcard::BelCardParser(); + shared_ptr belCards = parser->parseFile(filename); + for (auto it = belCards->getCards().begin(); it != belCards->getCards().end(); ++it) { + shared_ptr belcard = (*it); + LinphoneVCard *vcard = linphone_vcard_new(); + vcard->belcard = belcard; + result = ms_list_append(result, vcard); + } + } + } + return result; +} + extern "C" void linphone_vcard_set_full_name(LinphoneVCard *vcard, const char *name) { shared_ptr fn = belcard::BelCardGeneric::create(); fn->setValue(name); vcard->belcard->setFullName(fn); } -extern "C" const char* linphone_vcard_get_full_name(LinphoneVCard *vcard) { +extern "C" const char* linphone_vcard_get_full_name(const LinphoneVCard *vcard) { const char *result = vcard->belcard->getFullName() ? vcard->belcard->getFullName()->getValue().c_str() : NULL; return result; +} + +extern "C" MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vcard) { + MSList *result = NULL; + for (auto it = vcard->belcard->getImpp().begin(); it != vcard->belcard->getImpp().end(); ++it) { + const char *value = (*it)->getValue().c_str(); + if (strncmp(value, "sip:", 4) == 0) { + result = ms_list_append(result, (char *)value); + } + } + return result; } \ No newline at end of file diff --git a/coreapi/vcard.h b/coreapi/vcard.h index 7a2fbd42f..eaaab647a 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -35,9 +35,12 @@ typedef struct _LinphoneVCard LinphoneVCard; LINPHONE_PUBLIC LinphoneVCard* linphone_vcard_new(void); LINPHONE_PUBLIC void linphone_vcard_free(LinphoneVCard *vcard); +LINPHONE_PUBLIC MSList* linphone_vcard_new_from_vcard4_file(const char *file); LINPHONE_PUBLIC void linphone_vcard_set_full_name(LinphoneVCard *vcard, const char *name); -LINPHONE_PUBLIC const char* linphone_vcard_get_full_name(LinphoneVCard *vcard); +LINPHONE_PUBLIC const char* linphone_vcard_get_full_name(const LinphoneVCard *vcard); + +LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vcard); #ifdef __cplusplus } diff --git a/gtk/main.c b/gtk/main.c index ba91fd3b3..68522578f 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1832,6 +1832,21 @@ void linphone_gtk_show_keypad_checked(GtkCheckMenuItem *check_menu_item) { } } +void linphone_gtk_import_contacts(void) { + GtkWidget *mw = linphone_gtk_get_main_window(); + GtkWidget *dialog; + dialog = gtk_file_chooser_dialog_new ("Open File", (GtkWindow *)mw, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + LinphoneCore *lc = linphone_gtk_get_core(); + char *filename; + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + linphone_core_import_friends_from_vcard4_file(lc, filename); + g_free (filename); + linphone_gtk_show_friends(); + } + gtk_widget_destroy (dialog); +} + gboolean linphone_gtk_keypad_destroyed_handler(void) { GtkWidget *mw = linphone_gtk_get_main_window(); GtkWidget *show_keypad_item = linphone_gtk_get_widget(mw, "show_keypad_menu_item"); diff --git a/gtk/main.ui b/gtk/main.ui index 98dc3400a..2c8ce2d50 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -228,6 +228,21 @@ False + + + True + False + Import contacts + True + + + + + + True + False + + gtk-quit From 132f389bfde4c156f340dc9103fde93ecd193a86 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 14 Dec 2015 16:16:11 +0100 Subject: [PATCH 004/121] Fix crash when selected file doesn't contain any vcard --- coreapi/vcard.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 4d1a135b3..29b14b912 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -38,10 +38,10 @@ extern "C" void linphone_vcard_free(LinphoneVCard *vcard) { extern "C" MSList* linphone_vcard_new_from_vcard4_file(const char *filename) { MSList *result = NULL; - if (filename) { - if (ortp_file_exist(filename) == 0) { - belcard::BelCardParser *parser = new belcard::BelCardParser(); - shared_ptr belCards = parser->parseFile(filename); + if (filename && ortp_file_exist(filename) == 0) { + belcard::BelCardParser *parser = new belcard::BelCardParser(); + shared_ptr belCards = parser->parseFile(filename); + if (belCards) { for (auto it = belCards->getCards().begin(); it != belCards->getCards().end(); ++it) { shared_ptr belcard = (*it); LinphoneVCard *vcard = linphone_vcard_new(); From 47e0b04725f3c5d204adafb430fd42f6d5cf1c05 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 14 Dec 2015 17:43:20 +0100 Subject: [PATCH 005/121] Added export functions for contacts as vCards + added documentation for vCard API --- coreapi/friend.c | 25 ++++++++++++++++++++++ coreapi/linphonefriend.h | 23 +++++++++++++------- coreapi/vcard.cc | 4 ++++ coreapi/vcard.h | 46 ++++++++++++++++++++++++++++++++++++++++ gtk/main.c | 26 +++++++++++++++++------ gtk/main.ui | 11 +++++++++- 6 files changed, 119 insertions(+), 16 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index 6ed7df80f..ea2a62f34 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -834,6 +834,31 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * return count; } +void linphone_core_export_friends_as_vcard4_file(LinphoneCore *lc, const char *vcard_file) { + FILE *file = NULL; + MSList *friends = lc->friends; + + file = fopen(vcard_file, "w"); + if (file == NULL) { + ms_warning("Could not write %s ! Maybe it is read-only. Contacts will not be saved.", vcard_file); + return; + } + + while (friends != NULL && friends->data != NULL) { + LinphoneFriend *lf = (LinphoneFriend *)friends->data; + LinphoneVCard *vcard = linphone_friend_get_vcard(lf); + if (vcard) { + const char *vcard_text = linphone_vcard_as_vcard4_string(vcard); + fprintf(file, "%s", vcard_text); + } else { + ms_warning("Couldn't export friend %s because it doesn't have a vCard attached", linphone_address_as_string(linphone_friend_get_address(lf))); + } + friends = ms_list_next(friends); + } + + fclose(file); +} + BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriend); BELLE_SIP_INSTANCIATE_VPTR(LinphoneFriend, belle_sip_object_t, diff --git a/coreapi/linphonefriend.h b/coreapi/linphonefriend.h index 3682546ff..cd194f1d1 100644 --- a/coreapi/linphonefriend.h +++ b/coreapi/linphonefriend.h @@ -415,20 +415,20 @@ LINPHONE_PUBLIC void linphone_friend_unref(LinphoneFriend *lf); LINPHONE_PUBLIC LinphoneCore *linphone_friend_get_core(const LinphoneFriend *fr); /** - * Returns the VCard object associated to this friend, if any + * Returns the vCard object associated to this friend, if any * @param[in] fr LinphoneFriend object */ LINPHONE_PUBLIC LinphoneVCard* linphone_friend_get_vcard(LinphoneFriend *fr); /** - * Binds a VCard object to a friend + * Binds a vCard object to a friend * @param[in] fr LinphoneFriend object - * @param[in] vcard The VCard object to bind + * @param[in] vcard The vCard object to bind */ LINPHONE_PUBLIC void linphone_friend_set_vcard(LinphoneFriend *fr, LinphoneVCard *vcard); /** - * Creates a VCard object associated to this friend if there isn't one yet and if the full name is available, either by the parameter or the one in the friend's SIP URI + * Creates a vCard object associated to this friend if there isn't one yet and if the full name is available, either by the parameter or the one in the friend's SIP URI * @param[in] fr LinphoneFriend object * @param[in] name The full name of the friend or NULL to use the one from the friend's SIP URI * @return true if the vCard has been created, false if it wasn't possible (for exemple if name and the friend's SIP URI are null or if the friend's SIP URI doesn't have a display name), or if there is already one vcard @@ -437,19 +437,26 @@ LINPHONE_PUBLIC bool_t linphone_friend_create_vcard(LinphoneFriend *fr, const ch /** * Contructor same as linphone_friend_new() + linphone_friend_set_address() - * @param vcard a VCard object - * @return a new #LinphoneFriend with \link linphone_friend_get_vcard() vcard initialized \endlink + * @param vcard a vCard object + * @return a new #LinphoneFriend with \link linphone_friend_get_vcard() vCard initialized \endlink */ LINPHONE_PUBLIC LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard); /** - * Creates and adds LinphoneFriend objects to LinphoneCore from a file that contains the vcard(s) to parse + * Creates and adds LinphoneFriend objects to LinphoneCore from a file that contains the vCard(s) to parse * @param[in] lc the LinphoneCore object - * @param[in] vcard_file the path to a file that contains the vcard(s) to parse + * @param[in] vcard_file the path to a file that contains the vCard(s) to parse * @return the amount of linphone friends created */ LINPHONE_PUBLIC int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char *vcard_file); +/** + * Creates and export LinphoneFriend objects from LinphoneCore to a file using vCard 4 format + * @param[in] lc the LinphoneCore object + * @param[in] vcard_file the path to a file that will contain the vCards + */ +LINPHONE_PUBLIC void linphone_core_export_friends_as_vcard4_file(LinphoneCore *lc, const char *vcard_file); + /** * @} */ diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 29b14b912..3f71fddf2 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -53,6 +53,10 @@ extern "C" MSList* linphone_vcard_new_from_vcard4_file(const char *filename) { return result; } +extern "C" const char * linphone_vcard_as_vcard4_string(LinphoneVCard *vcard) { + return vcard->belcard->toFoldedString().c_str(); +} + extern "C" void linphone_vcard_set_full_name(LinphoneVCard *vcard, const char *name) { shared_ptr fn = belcard::BelCardGeneric::create(); fn->setValue(name); diff --git a/coreapi/vcard.h b/coreapi/vcard.h index eaaab647a..04d187b5f 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -31,17 +31,63 @@ extern "C" { #endif +/** + * @addtogroup buddy_list + * @{ + */ + typedef struct _LinphoneVCard LinphoneVCard; +/** + * Creates a LinphoneVCard object that has a pointer to an empty vCard + */ LINPHONE_PUBLIC LinphoneVCard* linphone_vcard_new(void); + +/** + * Deletes a LinphoneVCard object properly + * @param[in] vcard the LinphoneVCard to destroy + */ LINPHONE_PUBLIC void linphone_vcard_free(LinphoneVCard *vcard); + +/** + * Uses belcard to parse the content of a file and returns all the vcards it contains as LinphoneVCards, or NULL if it contains none. + * @param[in] file the path to the file to parse + * @return \mslist{LinphoneVCard} + */ LINPHONE_PUBLIC MSList* linphone_vcard_new_from_vcard4_file(const char *file); +/** + * Returns the vCard4 representation of the LinphoneVCard. + * @param[in] vcard the LinphoneVCard + * @return a const char * that represents the vcard + */ +LINPHONE_PUBLIC const char* linphone_vcard_as_vcard4_string(LinphoneVCard *vcard); + +/** + * Sets the FN attribute of the vCard (which is mandatory). + * @param[in] vcard the LinphoneVCard + * @param[in] name the display name to set for the vCard + */ LINPHONE_PUBLIC void linphone_vcard_set_full_name(LinphoneVCard *vcard, const char *name); + +/** + * Returns the FN attribute of the vCard, or NULL if it isn't set yet. + * @param[in] vcard the LinphoneVCard + * @return the display name of the vCard, or NULL + */ LINPHONE_PUBLIC const char* linphone_vcard_get_full_name(const LinphoneVCard *vcard); +/** + * Returns the list of SIP addresses (as const char *) in the vCard (all the IMPP attributes that has an URI value starting by "sip:") or NULL + * @param[in] vcard the LinphoneVCard + * @return \mslist{const char *} + */ LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vcard); +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/gtk/main.c b/gtk/main.c index 68522578f..ff71732c0 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1834,17 +1834,29 @@ void linphone_gtk_show_keypad_checked(GtkCheckMenuItem *check_menu_item) { void linphone_gtk_import_contacts(void) { GtkWidget *mw = linphone_gtk_get_main_window(); - GtkWidget *dialog; - dialog = gtk_file_chooser_dialog_new ("Open File", (GtkWindow *)mw, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + GtkWidget *dialog = gtk_file_chooser_dialog_new("Open vCard file", (GtkWindow *)mw, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { LinphoneCore *lc = linphone_gtk_get_core(); - char *filename; - filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); linphone_core_import_friends_from_vcard4_file(lc, filename); - g_free (filename); + g_free(filename); linphone_gtk_show_friends(); } - gtk_widget_destroy (dialog); + gtk_widget_destroy(dialog); +} + +void linphone_gtk_export_contacts(void) { + GtkWidget *mw = linphone_gtk_get_main_window(); + GtkWidget *dialog = gtk_file_chooser_dialog_new("Save vCards as", (GtkWindow *)mw, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); + gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); + + if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + LinphoneCore *lc = linphone_gtk_get_core(); + char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + linphone_core_export_friends_as_vcard4_file(lc, filename); + g_free(filename); + } + gtk_widget_destroy(dialog); } gboolean linphone_gtk_keypad_destroyed_handler(void) { diff --git a/gtk/main.ui b/gtk/main.ui index 2c8ce2d50..adab898aa 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -232,11 +232,20 @@ True False - Import contacts + Import contacts from vCards True + + + True + False + Export contacts as vCards + True + + + True From 91a10a6be982b076453a198b5b1390ef751f35cb Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 15 Dec 2015 10:56:06 +0100 Subject: [PATCH 006/121] Added methods to create LinphoneVCard list from buffer and also single LinphoneVCard from buffer too --- coreapi/friend.c | 2 +- coreapi/vcard.cc | 80 +++++++++++++++++++++++++++++++++--------------- coreapi/vcard.h | 16 +++++++++- 3 files changed, 71 insertions(+), 27 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index ea2a62f34..ef65b55db 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -818,7 +818,7 @@ LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard) { } int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char *vcard_file) { - MSList *vcards = linphone_vcard_new_from_vcard4_file(vcard_file); + MSList *vcards = linphone_vcard_list_from_vcard4_file(vcard_file); int count = 0; while (vcards != NULL && vcards->data != NULL) { diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 3f71fddf2..d5c22e76f 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -22,21 +22,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "belcard/belcard_parser.hpp" struct _LinphoneVCard { - shared_ptr belcard; + shared_ptr belCard; }; extern "C" LinphoneVCard* linphone_vcard_new(void) { - LinphoneVCard* vcard = (LinphoneVCard*) ms_new0(LinphoneVCard, 1); - vcard->belcard = belcard::BelCardGeneric::create(); - return vcard; + LinphoneVCard* vCard = (LinphoneVCard*) ms_new0(LinphoneVCard, 1); + vCard->belCard = belcard::BelCardGeneric::create(); + return vCard; } -extern "C" void linphone_vcard_free(LinphoneVCard *vcard) { - vcard->belcard.reset(); - ms_free(vcard); +extern "C" void linphone_vcard_free(LinphoneVCard *vCard) { + vCard->belCard.reset(); + ms_free(vCard); } -extern "C" MSList* linphone_vcard_new_from_vcard4_file(const char *filename) { +extern "C" MSList* linphone_vcard_list_from_vcard4_file(const char *filename) { MSList *result = NULL; if (filename && ortp_file_exist(filename) == 0) { belcard::BelCardParser *parser = new belcard::BelCardParser(); @@ -44,33 +44,63 @@ extern "C" MSList* linphone_vcard_new_from_vcard4_file(const char *filename) { if (belCards) { for (auto it = belCards->getCards().begin(); it != belCards->getCards().end(); ++it) { shared_ptr belcard = (*it); - LinphoneVCard *vcard = linphone_vcard_new(); - vcard->belcard = belcard; - result = ms_list_append(result, vcard); + LinphoneVCard *vCard = linphone_vcard_new(); + vCard->belCard = belcard; + result = ms_list_append(result, vCard); } } } return result; } -extern "C" const char * linphone_vcard_as_vcard4_string(LinphoneVCard *vcard) { - return vcard->belcard->toFoldedString().c_str(); -} - -extern "C" void linphone_vcard_set_full_name(LinphoneVCard *vcard, const char *name) { - shared_ptr fn = belcard::BelCardGeneric::create(); - fn->setValue(name); - vcard->belcard->setFullName(fn); -} - -extern "C" const char* linphone_vcard_get_full_name(const LinphoneVCard *vcard) { - const char *result = vcard->belcard->getFullName() ? vcard->belcard->getFullName()->getValue().c_str() : NULL; +extern "C" MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer) { + MSList *result = NULL; + if (buffer) { + belcard::BelCardParser *parser = new belcard::BelCardParser(); + shared_ptr belCards = parser->parse(buffer); + if (belCards) { + for (auto it = belCards->getCards().begin(); it != belCards->getCards().end(); ++it) { + shared_ptr belCard = (*it); + LinphoneVCard *vCard = linphone_vcard_new(); + vCard->belCard = belCard; + result = ms_list_append(result, vCard); + } + } + } return result; } -extern "C" MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vcard) { +extern "C" LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer) { + LinphoneVCard *vCard = NULL; + if (buffer) { + belcard::BelCardParser *parser = new belcard::BelCardParser(); + shared_ptr belCard = parser->parseOne(buffer); + if (belCard) { + vCard = linphone_vcard_new(); + vCard->belCard = belCard; + } + } + return vCard; +} + +extern "C" const char * linphone_vcard_as_vcard4_string(LinphoneVCard *vCard) { + return vCard->belCard->toFoldedString().c_str(); +} + +extern "C" void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name) { + shared_ptr fn = belcard::BelCardGeneric::create(); + fn->setValue(name); + vCard->belCard->setFullName(fn); +} + +extern "C" const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard) { + const char *result = vCard->belCard->getFullName() ? vCard->belCard->getFullName()->getValue().c_str() : NULL; + return result; +} + +extern "C" MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) { MSList *result = NULL; - for (auto it = vcard->belcard->getImpp().begin(); it != vcard->belcard->getImpp().end(); ++it) { + for (auto it = vCard->belCard->getImpp().begin(); it != vCard->belCard->getImpp().end(); ++it) { const char *value = (*it)->getValue().c_str(); if (strncmp(value, "sip:", 4) == 0) { result = ms_list_append(result, (char *)value); diff --git a/coreapi/vcard.h b/coreapi/vcard.h index 04d187b5f..e45dc01a5 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -54,7 +54,21 @@ LINPHONE_PUBLIC void linphone_vcard_free(LinphoneVCard *vcard); * @param[in] file the path to the file to parse * @return \mslist{LinphoneVCard} */ -LINPHONE_PUBLIC MSList* linphone_vcard_new_from_vcard4_file(const char *file); +LINPHONE_PUBLIC MSList* linphone_vcard_list_from_vcard4_file(const char *file); + +/** + * Uses belcard to parse the content of a buffer and returns all the vcards it contains as LinphoneVCards, or NULL if it contains none. + * @param[in] buffer the buffer to parse + * @return \mslist{LinphoneVCard} + */ +LINPHONE_PUBLIC MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer); + +/** + * Uses belcard to parse the content of a buffer and returns one vCard if possible, or NULL otherwise. + * @param[in] buffer the buffer to parse + * @return a LinphoneVCard if one could be parsed, or NULL otherwise + */ +LINPHONE_PUBLIC LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer); /** * Returns the vCard4 representation of the LinphoneVCard. From f6edea6eec1678dccb4f168e6baa6fd55890b3b7 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 15 Dec 2015 17:13:00 +0100 Subject: [PATCH 007/121] Use linphone_core_get_friend_list to ease future merge with friends lists + added method to add SIP address into vCard --- coreapi/friend.c | 2 +- coreapi/vcard.cc | 6 ++++++ coreapi/vcard.h | 29 ++++++++++++++++++----------- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index ef65b55db..1c173aba9 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -836,7 +836,7 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * void linphone_core_export_friends_as_vcard4_file(LinphoneCore *lc, const char *vcard_file) { FILE *file = NULL; - MSList *friends = lc->friends; + const MSList *friends = linphone_core_get_friend_list(lc); file = fopen(vcard_file, "w"); if (file == NULL) { diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index d5c22e76f..7e049f87d 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -98,6 +98,12 @@ extern "C" const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard) return result; } +extern "C" void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char *sip_address) { + shared_ptr impp = belcard::BelCardGeneric::create(); + impp->setValue(sip_address); + vCard->belCard->addImpp(impp); +} + extern "C" MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) { MSList *result = NULL; for (auto it = vCard->belCard->getImpp().begin(); it != vCard->belCard->getImpp().end(); ++it) { diff --git a/coreapi/vcard.h b/coreapi/vcard.h index e45dc01a5..ac3f4d296 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -45,9 +45,9 @@ LINPHONE_PUBLIC LinphoneVCard* linphone_vcard_new(void); /** * Deletes a LinphoneVCard object properly - * @param[in] vcard the LinphoneVCard to destroy + * @param[in] vCard the LinphoneVCard to destroy */ -LINPHONE_PUBLIC void linphone_vcard_free(LinphoneVCard *vcard); +LINPHONE_PUBLIC void linphone_vcard_free(LinphoneVCard *vCard); /** * Uses belcard to parse the content of a file and returns all the vcards it contains as LinphoneVCards, or NULL if it contains none. @@ -72,31 +72,38 @@ LINPHONE_PUBLIC LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char /** * Returns the vCard4 representation of the LinphoneVCard. - * @param[in] vcard the LinphoneVCard - * @return a const char * that represents the vcard + * @param[in] vCard the LinphoneVCard + * @return a const char * that represents the vCard */ -LINPHONE_PUBLIC const char* linphone_vcard_as_vcard4_string(LinphoneVCard *vcard); +LINPHONE_PUBLIC const char* linphone_vcard_as_vcard4_string(LinphoneVCard *vCard); /** * Sets the FN attribute of the vCard (which is mandatory). - * @param[in] vcard the LinphoneVCard + * @param[in] vCard the LinphoneVCard * @param[in] name the display name to set for the vCard */ -LINPHONE_PUBLIC void linphone_vcard_set_full_name(LinphoneVCard *vcard, const char *name); +LINPHONE_PUBLIC void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name); /** * Returns the FN attribute of the vCard, or NULL if it isn't set yet. - * @param[in] vcard the LinphoneVCard + * @param[in] vCard the LinphoneVCard * @return the display name of the vCard, or NULL */ -LINPHONE_PUBLIC const char* linphone_vcard_get_full_name(const LinphoneVCard *vcard); +LINPHONE_PUBLIC const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard); + +/** + * Adds a SIP address in the vCard, using the IMPP property + * @param[in] vCard the LinphoneVCard + * @param[in] sip_address the SIP address to add + */ +LINPHONE_PUBLIC void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char *sip_address); /** * Returns the list of SIP addresses (as const char *) in the vCard (all the IMPP attributes that has an URI value starting by "sip:") or NULL - * @param[in] vcard the LinphoneVCard + * @param[in] vCard the LinphoneVCard * @return \mslist{const char *} */ -LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vcard); +LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard); /** * @} From 0a59544a446f3bf244b88d9bb2cac27269d6eb3c Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 16 Dec 2015 10:51:17 +0100 Subject: [PATCH 008/121] Added checks for null values in vcard.cc and added new methods to manipulate sip addresses in vcard from friend --- coreapi/friend.c | 24 ++++++++++++++---------- coreapi/vcard.cc | 37 +++++++++++++++++++++++++++++++++++++ coreapi/vcard.h | 14 ++++++++++++++ 3 files changed, 65 insertions(+), 10 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index 1c173aba9..17ab1fda7 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -199,10 +199,12 @@ void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char } int linphone_friend_set_address(LinphoneFriend *lf, const LinphoneAddress *addr){ - LinphoneAddress *fr=linphone_address_clone(addr); + LinphoneAddress *fr = linphone_address_clone(addr); + linphone_address_clean(fr); - if (lf->uri!=NULL) linphone_address_destroy(lf->uri); - lf->uri=fr; + if (lf->uri != NULL) linphone_address_destroy(lf->uri); + lf->uri = fr; + return 0; } @@ -211,17 +213,19 @@ int linphone_friend_set_name(LinphoneFriend *lf, const char *name){ LinphoneVCard *vcard = NULL; if (fr == NULL){ - ms_error("linphone_friend_set_sip_addr() must be called before linphone_friend_set_name()."); + ms_error("linphone_friend_set_address() must be called before linphone_friend_set_name()."); return -1; } - linphone_address_set_display_name(fr,name); - + linphone_address_set_display_name(fr, name); vcard = linphone_friend_get_vcard(lf); if (!vcard) { linphone_friend_create_vcard(lf, name); - } else { + vcard = linphone_friend_get_vcard(lf); + } + if (vcard) { linphone_vcard_set_full_name(vcard, name); + linphone_vcard_edit_main_sip_address(vcard, linphone_address_as_string_uri_only(fr)); } return 0; @@ -771,10 +775,10 @@ bool_t linphone_friend_create_vcard(LinphoneFriend *fr, const char *name) { } else { const char *displayName = linphone_address_get_display_name(addr); if (!displayName) { - ms_error("Friend's URI doesn't have a display name"); - return FALSE; + fullName = linphone_address_get_username(addr); + } else { + fullName = displayName; } - fullName = displayName; } if (!fullName) { diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 7e049f87d..2cdc8a677 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -32,6 +32,8 @@ extern "C" LinphoneVCard* linphone_vcard_new(void) { } extern "C" void linphone_vcard_free(LinphoneVCard *vCard) { + if (!vCard) return; + vCard->belCard.reset(); ms_free(vCard); } @@ -84,28 +86,63 @@ extern "C" LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buff } extern "C" const char * linphone_vcard_as_vcard4_string(LinphoneVCard *vCard) { + if (!vCard) return NULL; + return vCard->belCard->toFoldedString().c_str(); } extern "C" void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name) { + if (!vCard || !name) return; + shared_ptr fn = belcard::BelCardGeneric::create(); fn->setValue(name); vCard->belCard->setFullName(fn); } extern "C" const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard) { + if (!vCard) return NULL; + const char *result = vCard->belCard->getFullName() ? vCard->belCard->getFullName()->getValue().c_str() : NULL; return result; } extern "C" void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char *sip_address) { + if (!vCard || !sip_address) return; + shared_ptr impp = belcard::BelCardGeneric::create(); impp->setValue(sip_address); vCard->belCard->addImpp(impp); } +extern "C" void linphone_vcard_remove_sip_address(LinphoneVCard *vCard, const char *sip_address) { + if (!vCard) return; + + for (auto it = vCard->belCard->getImpp().begin(); it != vCard->belCard->getImpp().end(); ++it) { + const char *value = (*it)->getValue().c_str(); + if (strcmp(value, sip_address) == 0) { + vCard->belCard->removeImpp(*it); + break; + } + } +} + +extern "C" void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const char *sip_address) { + if (!vCard || !sip_address) return; + + if (vCard->belCard->getImpp().size() > 0) { + const shared_ptr impp = vCard->belCard->getImpp().front(); + impp->setValue(sip_address); + } else { + shared_ptr impp = belcard::BelCardGeneric::create(); + impp->setValue(sip_address); + vCard->belCard->addImpp(impp); + } +} + extern "C" MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) { MSList *result = NULL; + if (!vCard) return NULL; + for (auto it = vCard->belCard->getImpp().begin(); it != vCard->belCard->getImpp().end(); ++it) { const char *value = (*it)->getValue().c_str(); if (strncmp(value, "sip:", 4) == 0) { diff --git a/coreapi/vcard.h b/coreapi/vcard.h index ac3f4d296..4ad094915 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -98,6 +98,20 @@ LINPHONE_PUBLIC const char* linphone_vcard_get_full_name(const LinphoneVCard *vC */ LINPHONE_PUBLIC void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char *sip_address); +/** + * Removes a SIP address in the vCard (if it exists), using the IMPP property + * @param[in] vCard the LinphoneVCard + * @param[in] sip_address the SIP address to remove + */ +LINPHONE_PUBLIC void linphone_vcard_remove_sip_address(LinphoneVCard *vCard, const char *sip_address); + +/** + * Edits the preferred SIP address in the vCard (or the first one), using the IMPP property + * @param[in] vCard the LinphoneVCard + * @param[in] sip_address the new SIP address + */ +LINPHONE_PUBLIC void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const char *sip_address); + /** * Returns the list of SIP addresses (as const char *) in the vCard (all the IMPP attributes that has an URI value starting by "sip:") or NULL * @param[in] vCard the LinphoneVCard From 698c3e55cdb4ea4f9956835aedaa22fddb0562c3 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 16 Dec 2015 10:58:52 +0100 Subject: [PATCH 009/121] Added vcard tester (currently empty) --- tester/Makefile.am | 1 + tester/liblinphone_tester.h | 1 + tester/tester.c | 1 + tester/vcard_tester.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 35 insertions(+) create mode 100644 tester/vcard_tester.c diff --git a/tester/Makefile.am b/tester/Makefile.am index 40dabb7e2..b330714eb 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -135,6 +135,7 @@ liblinphonetester_la_SOURCES = \ tester.c \ upnp_tester.c \ video_tester.c \ + vcard_tester.c \ common/bc_tester_utils.c liblinphonetester_ladir = $(includedir)/linphone diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index 4cbe28046..cd51b4772 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -53,6 +53,7 @@ extern test_suite_t video_test_suite; extern test_suite_t multicast_call_test_suite; extern test_suite_t multi_call_test_suite; extern test_suite_t proxy_config_test_suite; +extern test_suite_t vcard_test_suite; #if HAVE_SIPP extern test_suite_t complex_sip_call_test_suite; #endif diff --git a/tester/tester.c b/tester/tester.c index ad3380993..ad97955e9 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -473,6 +473,7 @@ void liblinphone_tester_add_suites() { #if HAVE_SIPP bc_tester_add_suite(&complex_sip_call_test_suite); #endif + bc_tester_add_suite(&vcard_test_suite); } static int linphone_core_manager_get_max_audio_bw_base(const int array[],int array_size) { diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c new file mode 100644 index 000000000..21e38d2d3 --- /dev/null +++ b/tester/vcard_tester.c @@ -0,0 +1,32 @@ +/* + vcard_tester.c + Copyright (C) 2015 Belledonne Communications SARL + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#include "linphonecore.h" +#include "private.h" +#include "liblinphone_tester.h" + +test_t vcard_tests[] = { + +}; + +test_suite_t vcard_test_suite = { + "VCard", NULL, NULL, + liblinphone_tester_before_each, liblinphone_tester_after_each, + sizeof(vcard_tests) / sizeof(vcard_tests[0]), vcard_tests +}; From 8c823fc0396bf8104a0d192bb0e423c5e8bf889a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 16 Dec 2015 11:54:34 +0100 Subject: [PATCH 010/121] Added import friends from vcards test --- coreapi/friend.c | 2 +- tester/Makefile.am | 2 +- tester/common/vcards.vcf | 22 ++++++++++++++++++++++ tester/vcard_tester.c | 27 +++++++++++++++++++++++++-- 4 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 tester/common/vcards.vcf diff --git a/coreapi/friend.c b/coreapi/friend.c index 17ab1fda7..7bfe6b3b5 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -212,7 +212,7 @@ int linphone_friend_set_name(LinphoneFriend *lf, const char *name){ LinphoneAddress *fr = lf->uri; LinphoneVCard *vcard = NULL; - if (fr == NULL){ + if (fr == NULL) { ms_error("linphone_friend_set_address() must be called before linphone_friend_set_name()."); return -1; } diff --git a/tester/Makefile.am b/tester/Makefile.am index b330714eb..66e0acc0e 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -72,7 +72,7 @@ RCFILES = \ IMAGE_FILES = images/nowebcamCIF.jpg -COMMON_FILE = common/bc_completion +COMMON_FILE = common/bc_completion common/vcards.vcf EXTRA_DIST = tester_hosts\ messages.db\ diff --git a/tester/common/vcards.vcf b/tester/common/vcards.vcf new file mode 100644 index 000000000..7ffd718c6 --- /dev/null +++ b/tester/common/vcards.vcf @@ -0,0 +1,22 @@ +BEGIN:VCARD +VERSION:4.0 +KIND:individual +FN:Sylvain Berfini +N:Berfini;Sylvain;Pascal;; +GENDER:M +IMPP;PREF=1;TYPE=work:sip:sylvain@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +KIND:individual +FN:François Grisez +N:Grisez;François;;; +IMPP;TYPE=work:sip:francois@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +KIND:individual +FN:Margaux Clerc +GENDER:F +IMPP:sip:margaux@sip.linphone.org +END:VCARD diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 21e38d2d3..992c03015 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -16,13 +16,36 @@ along with this program. If not, see . */ - #include "linphonecore.h" #include "private.h" #include "liblinphone_tester.h" -test_t vcard_tests[] = { +static void linphone_vcard_import_friends_test(void) { + LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + const MSList *friends = linphone_core_get_friend_list(manager->lc); + int count = 0; + BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); + count = linphone_core_import_friends_from_vcard4_file(manager->lc, bc_tester_res("common/vcards.vcf")); + BC_ASSERT_EQUAL(count, 3, int, "%d"); + friends = linphone_core_get_friend_list(manager->lc); + BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d"); + + linphone_core_manager_destroy(manager); +} + +static void linphone_vcard_export_friends_test(void) { + +} + +static void linphone_vcard_create_edit_friends_test(void) { + +} + +test_t vcard_tests[] = { + { "Import friends from vCards", linphone_vcard_import_friends_test }, + { "Export friends to vCards", linphone_vcard_export_friends_test }, + { "Create and edit friends' vCards", linphone_vcard_create_edit_friends_test }, }; test_suite_t vcard_test_suite = { From 45ff93019055fbeaed853367c89efea96dedfc0e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 17 Dec 2015 10:10:39 +0100 Subject: [PATCH 011/121] Improved import/export test --- tester/vcard_tester.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 992c03015..e7931c7c7 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -20,32 +20,40 @@ #include "private.h" #include "liblinphone_tester.h" -static void linphone_vcard_import_friends_test(void) { +static char *create_filepath(const char *dir, const char *filename, const char *ext) { + return ms_strdup_printf("%s/%s.%s", dir, filename, ext); +} + +static void linphone_vcard_import_export_friends_test(void) { LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + char *import_filepath = bc_tester_res("common/vcards.vcf"); + char *export_filepath = create_filepath(bc_tester_get_writable_dir_prefix(), "export_vcards", "vcf"); const MSList *friends = linphone_core_get_friend_list(manager->lc); int count = 0; BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); - count = linphone_core_import_friends_from_vcard4_file(manager->lc, bc_tester_res("common/vcards.vcf")); + count = linphone_core_import_friends_from_vcard4_file(manager->lc, import_filepath); BC_ASSERT_EQUAL(count, 3, int, "%d"); friends = linphone_core_get_friend_list(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d"); + linphone_core_export_friends_as_vcard4_file(manager->lc, export_filepath); + + manager->lc->friends = ms_list_free(manager->lc->friends); + friends = linphone_core_get_friend_list(manager->lc); + BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); + + count = linphone_core_import_friends_from_vcard4_file(manager->lc, export_filepath); + BC_ASSERT_EQUAL(count, 3, int, "%d"); + friends = linphone_core_get_friend_list(manager->lc); + BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d"); + + remove(export_filepath); linphone_core_manager_destroy(manager); } -static void linphone_vcard_export_friends_test(void) { - -} - -static void linphone_vcard_create_edit_friends_test(void) { - -} - test_t vcard_tests[] = { - { "Import friends from vCards", linphone_vcard_import_friends_test }, - { "Export friends to vCards", linphone_vcard_export_friends_test }, - { "Create and edit friends' vCards", linphone_vcard_create_edit_friends_test }, + { "Import / Export friends from vCards", linphone_vcard_import_export_friends_test }, }; test_suite_t vcard_test_suite = { From 79086201c051df8d8917b06fa654ea8d349a8ecc Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 17 Dec 2015 11:42:36 +0100 Subject: [PATCH 012/121] Fix memory leak (parser not deleted) --- coreapi/vcard.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 2cdc8a677..c50043e03 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -51,6 +51,7 @@ extern "C" MSList* linphone_vcard_list_from_vcard4_file(const char *filename) { result = ms_list_append(result, vCard); } } + delete parser; } return result; } @@ -68,6 +69,7 @@ extern "C" MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer) { result = ms_list_append(result, vCard); } } + delete parser; } return result; } @@ -81,6 +83,7 @@ extern "C" LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buff vCard = linphone_vcard_new(); vCard->belCard = belCard; } + delete parser; } return vCard; } From 9b6a6ca7a52bef59e755e3978efafa92c11d2f3a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 17 Dec 2015 14:24:22 +0100 Subject: [PATCH 013/121] Improve import friends from vcard time by bypassing a few checks + added test to calculate 1000 vcards import time --- coreapi/friend.c | 34 +- coreapi/private.h | 2 + tester/Makefile.am | 2 +- tester/common/thousand_vcards.vcf | 8542 +++++++++++++++++++++++++++++ tester/vcard_tester.c | 19 + 5 files changed, 8583 insertions(+), 16 deletions(-) create mode 100644 tester/common/thousand_vcards.vcf diff --git a/coreapi/friend.c b/coreapi/friend.c index 7bfe6b3b5..44a764718 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -508,28 +508,32 @@ LinphoneFriend * linphone_core_create_friend_with_address(LinphoneCore *lc, cons return linphone_friend_new_with_address(address); } -void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) -{ - ms_return_if_fail(lf->lc==NULL); - ms_return_if_fail(lf->uri!=NULL); - if (ms_list_find(lc->friends,lf)!=NULL){ - char *tmp=NULL; - const LinphoneAddress *addr=linphone_friend_get_address(lf); - if (addr) tmp=linphone_address_as_string(addr); +void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) { + ms_return_if_fail(!lf->lc); + if (!lf->uri) { + return; // Do not abort if friend doesn't have a SIP URI + } + + if (ms_list_find(lc->friends, lf)) { + char *tmp = NULL; + const LinphoneAddress *addr = linphone_friend_get_address(lf); + if (addr) tmp = linphone_address_as_string(addr); ms_warning("Friend %s already in list, ignored.", tmp ? tmp : "unknown"); if (tmp) ms_free(tmp); - return ; + return; } - lc->friends=ms_list_append(lc->friends,linphone_friend_ref(lf)); - if (ms_list_find(lc->subscribers, lf)){ + linphone_core_import_friend(lc, lf); + if (ms_list_find(lc->subscribers, lf)) { /*if this friend was in the pending subscriber list, now remove it from this list*/ lc->subscribers = ms_list_remove(lc->subscribers, lf); linphone_friend_unref(lf); } - lf->lc=lc; - if ( linphone_core_ready(lc)) linphone_friend_apply(lf,lc); - else lf->commit=TRUE; - return ; +} + +void linphone_core_import_friend(LinphoneCore *lc, LinphoneFriend *lf) { + lc->friends = ms_list_append(lc->friends, linphone_friend_ref(lf)); + if (linphone_core_ready(lc)) linphone_friend_apply(lf, lc); + else lf->commit = TRUE; } void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* fl){ diff --git a/coreapi/private.h b/coreapi/private.h index 2190af8e3..1bd69a40a 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1399,6 +1399,8 @@ bool_t linphone_core_lime_for_file_sharing_enabled(const LinphoneCore *lc); BELLE_SIP_DECLARE_VPTR(LinphoneTunnelConfig); int linphone_core_get_default_proxy_config_index(LinphoneCore *lc); + +void linphone_core_import_friend(LinphoneCore *lc, LinphoneFriend *lf); #ifdef __cplusplus } diff --git a/tester/Makefile.am b/tester/Makefile.am index 66e0acc0e..043ec3045 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -72,7 +72,7 @@ RCFILES = \ IMAGE_FILES = images/nowebcamCIF.jpg -COMMON_FILE = common/bc_completion common/vcards.vcf +COMMON_FILE = common/bc_completion common/vcards.vcf common/thousand_vcards.vcf EXTRA_DIST = tester_hosts\ messages.db\ diff --git a/tester/common/thousand_vcards.vcf b/tester/common/thousand_vcards.vcf new file mode 100644 index 000000000..39552174a --- /dev/null +++ b/tester/common/thousand_vcards.vcf @@ -0,0 +1,8542 @@ +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:sharyn@sip.linphone.org +ADR:;;6390 Cotton Plant Parkway;Bingen;WA;98605; +FN:Sharyn Langford +GENDER:U +N:Langford;Sharyn;;; +EMAIL:sharyn@consequatvelfeugiat.net +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19851007 +N:Saunders;Lucretia;;; +FN:Lucretia Saunders +ORG:Industries Bell +EMAIL:lucretia.saunders@wisilobortis.us +NOTE:Veniamquis lorem ut praesent praesent exerci iriuredolor exerci. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(207)611-3176 +BDAY:19690513 +FN:Reuben Kinsey +EMAIL:r.kinsey@sitdelenit.info +N:Kinsey;Reuben;;; +GENDER:U +IMPP:sip:reuben@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(878)753-3993 +EMAIL:bryant.correa@veldignissim.gov +FN:Bryant Correa +IMPP:sip:bryant@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Electronic Network Provider +IMPP:sip:herman@sip.linphone.org +GENDER:U +BDAY:19560928 +FN:Herman Lerma +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Dexter Stratton +BDAY:19870819 +IMPP:sip:dexter@sip.linphone.org +TEL:tel:(878)866-5600 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Oma Corbitt +TEL:tel:(878)823-7932 +ADR:;;6537 Hunters Den Drive;Antioch;TN;37011; +IMPP:sip:oma@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:velma@sip.linphone.org +FN:Velma Hoffmann +ORG:Signal Alpha +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:deirdre@sip.linphone.org +FN:Deirdre Proffitt +BDAY:19800818 +NOTE:Vel elitsed eu volutpat ad in minim ea et in luptatum qui. +ORG:Venture Contract People +GENDER:O +N:Proffitt;Deirdre;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Ladonna Broome +ORG:Hill Research +IMPP:sip:ladonna@sip.linphone.org +ADR:;;2151 Hidden Harbor Drive;Wallingford;CT;06495; +TEL:tel:(586)347-1188 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Griffis;Hattie;;; +ORG:Adventure Construction Star +FN:Hattie Griffis +ADR:;;8653 Sanders Hill Trail;Paoli;IN;47454; +GENDER:F +NOTE:Duis vel aliquam suscipit zzril autem dolore nulla tationullamcorper vero. +TEL:tel:(313)364-7475 +EMAIL:hattie@facilisipraesent.gov +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Griselda German +EMAIL:g.german@luptatumvulputate.gov +IMPP:sip:griselda@sip.linphone.org +BDAY:19361102 +ORG:Advanced Adventure Vision +NOTE:Exerci vel ad in delenitaugue amet euismod ex facilisi lobortis. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;6500 Bayou River Way;Friendship;MD;20758; +BDAY:19850122 +TEL:tel:(620)112-3291 +EMAIL:joe@lobortisvero.net +FN:Joe Adams +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Delma Lunn +EMAIL:delma.lunn@euismodeum.us +ADR:;;8971 Clarington Trail;New Sharon;IA;50207; +NOTE:Vel feugiat iusto facilisi iustoodio nibh delenit nisl commodoconsequat erat lobortis ea nostrud lorem. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Meredith Rider +ORG:Omega Resource Innovation +BDAY:19690221 +N:Rider;Meredith;;; +NOTE:Illum amet euismod minim adipiscing veniam aliquam ullamcorper ad. +ADR:;;2015 Kellywood Street;Felt;ID;83424; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19720425 +GENDER:O +ORG:Net Pacific Electronic +NOTE:Adipiscing iusto esse eros eufeugiat ad iriure nibh. +FN:Lawerence Ivey +N:Ivey;Lawerence;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +ADR:;;2068 Rutherford Avenue;Bridgeport;NY;13030; +IMPP:sip:alyce@sip.linphone.org +BDAY:19811225 +FN:Alyce Goff +N:Goff;Alyce;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;1322 Shelton Cove;Allen;KY;41601; +FN:Taryn Spear +TEL:tel:(567)188-2497 +NOTE:Eum delenit facilisi duis qui minim in laoreet illum nostrud nulla dolore. +N:Spear;Taryn;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:ezequiel@sip.linphone.org +NOTE:Vulputate elitsed iusto consequat blandit nostrud ullamcorper aliquip diam ad. +FN:Ezequiel Irizarry +N:Irizarry;Ezequiel;;; +GENDER:N +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Colburn;Lucinda;;; +FN:Lucinda Colburn +IMPP:sip:lucinda@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Covington;Scott;;; +NOTE:Autem consequat Utwisi illum hendrerit. +EMAIL:scott@commodoconsequatzzril.net +FN:Scott Covington +BDAY:19361219 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19551018 +FN:Hank Kirchner +GENDER:O +ORG:Net People Building +IMPP:sip:hank@sip.linphone.org +ADR:;;5121 Saint Croix Circle;Shelly;MN;56581; +NOTE:Iusto blandit velit dignissim lobortis vel tation eu consectetuer nostrud at ea ex. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:South Telecom Signal +N:Lavender;Leticia;;; +EMAIL:l.lavender@tationluptatum.info +NOTE:Consectetuer eros ut ex molestie tation nulla feugait ullamcorper amet iriure amet vel. +FN:Leticia Lavender +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:r.corwin@molestiedolor.tv +FN:Randi Corwin +ADR:;;3010 Meadow Run Street;West Columbia;SC;29172; +ORG:Architecture North Data +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19730213 +EMAIL:errol@facilisisadipiscing.gov +IMPP:sip:errol@sip.linphone.org +TEL:tel:(716)978-8810 +FN:Errol Whitley +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Virtual Speed +FN:Angelique Link +IMPP:sip:angelique@sip.linphone.org +NOTE:Nonummy commodo ad esse aliquip exerci nulla enim nulla luptatum tation. +TEL:tel:(409)356-3785 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Mann;Carlton;;; +FN:Carlton Mann +IMPP:sip:carlton@sip.linphone.org +NOTE:Ad blandit duis delenitaugue ea eros consequat dolor facilisi elitsed veniam praesent velit. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;4643 Hawksprings Street;West Point;GA;31833; +IMPP:sip:nelson@sip.linphone.org +N:Seaton;Nelson;;; +FN:Nelson Seaton +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Orval Patterson +TEL:tel:(330)223-2469 +EMAIL:orval@exutwisi.net +ADR:;;6015 Willowbend Cove;Tacoma;WA;98445; +IMPP:sip:orval@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:b.mclain@feugiatautem.edu +GENDER:O +TEL:tel:(971)875-6507 +FN:Brenna Mclain +NOTE:Ut molestie delenitaugue velit augue duis aliquip commodo at. +ORG:West Frontier +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +FN:Jeana Wilmoth +IMPP:sip:jeana@sip.linphone.org +NOTE:Vel wisi zzril nonummy laoreet tincidunt augue dolore vel delenitaugue dolor ut. +ADR:;;9030 Country Place Lane;Angola;IN;46703; +N:Wilmoth;Jeana;;; +ORG:Signal Systems Star +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Dancy;Rick;;; +ORG:Application Federated Source +EMAIL:rick.dancy@doloreduis.us +FN:Rick Dancy +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Lance Arthur +ADR:;;9308 Panama Street;Ozark;MO;65721; +BDAY:19350607 +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19630914 +FN:Seymour Catlett +ADR:;;2995 Silkwood Avenue;Malvern;PA;19355; +EMAIL:seymour@velaliquam.edu +IMPP:sip:seymour@sip.linphone.org +GENDER:N +N:Catlett;Seymour;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:elsie@doloreea.eu +FN:Elsie Fish +ADR:;;4060 Blackberry Ridge Way;Greenbrier;AR;72058; +BDAY:19530903 +N:Fish;Elsie;;; +ORG:Net Max +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:c.lanier@eroseuismod.info +GENDER:F +NOTE:Minim dolore praesent eum nulla autem luptatumzzril dolore aliquip eros veniam. +ORG:Future Hill Vision +TEL:tel:(959)503-7251 +FN:Carolyn Lanier +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Network Data Solutions +TEL:tel:(603)579-5143 +BDAY:19780623 +IMPP:sip:rogelio@sip.linphone.org +FN:Rogelio Headrick +EMAIL:rogelio.headrick@etmolestie.tv +ADR:;;4956 Oakes Lane;Bible School Park;NY;13737; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Design Internet Venture +N:Greenlee;Adolfo;;; +EMAIL:adolfo.greenlee@wisietaccumsan.gov +FN:Adolfo Greenlee +NOTE:Duis dignissim vero dolor adipiscing dolore consectetuer. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Solutions Electronic Application +EMAIL:a.suarez@iriuredolorconsequat.com +FN:Abdul Suarez +ADR:;;1212 Valley Crest Trail;Henderson;CO;80640; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:leonardo@sip.linphone.org +GENDER:O +FN:Leonardo Sheridan +BDAY:19530106 +EMAIL:leonardo@blanditdiam.net +ORG:Star Net West +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:p.teel@etdolore.info +FN:Polly Teel +ORG:Signal Atlantic Contract +IMPP:sip:polly@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Vel blandit et dignissim veniamquis dolore ea accumsan nostrud vulputate lorem. +FN:Haydee Washburn +GENDER:O +ORG:Universal Vision Atlantic +N:Washburn;Haydee;;; +IMPP:sip:haydee@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Herlinda Montez +ORG:Interactive Venture Future +NOTE:Exerci dolor suscipit ex tationullamcorper vero consequat. +BDAY:19501105 +IMPP:sip:herlinda@sip.linphone.org +ADR:;;7219 Anchorage Drive;Stirling;NJ;07980; +EMAIL:herlinda.montez@commodoconsequatvulputate.us +GENDER:N +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Nolan Mcclain +EMAIL:n.mcclain@hendreritillum.eu +N:Mcclain;Nolan;;; +IMPP:sip:nolan@sip.linphone.org +NOTE:Feugait tincidunt velit wisi praesent vel nulla. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Duis suscipit blandit molestie dignissim vel exerci iriure lobortis aliquip diam. +N:Quinonez;Minh;;; +BDAY:19800208 +FN:Minh Quinonez +EMAIL:minh.quinonez@nostrudfeugait.org +GENDER:O +ADR:;;8329 Port Charlotte Avenue;Keiser;AR;72351; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +FN:Alexandria Hermann +NOTE:Nulla veniam consectetuer dolore sit. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:tony@sip.linphone.org +BDAY:19491115 +NOTE:Qui ullamcorper eu ex zzril illum molestie iriuredolor nostrud in facilisis wisi. +TEL:tel:(907)209-4202 +FN:Tony Comstock +ADR:;;3668 Cordie Lee Way;South West City;MO;64863; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Dixie Earnest +BDAY:19390408 +TEL:tel:(701)141-8626 +EMAIL:dixie.earnest@tationullamcorperluptatum.us +ORG:South Bell Pacific +NOTE:Doloremagna molestie facilisi iustoodio commodoconsequat vero delenit. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Eugenia Begley +TEL:tel:(318)345-2422 +ADR:;;2388 La Costa Way;Blodgett Mills;NY;13738; +NOTE:Nulla at feugiat commodo nulla dolore exerci eum eu vero. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(240)310-7670 +ADR:;;7146 Capital Lane;Oriental;NC;28571; +IMPP:sip:arturo@sip.linphone.org +FN:Arturo Haddad +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Miller;Fermin;;; +GENDER:M +FN:Fermin Miller +ADR:;;7855 Highland Way;Monument Valley;UT;84536; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Solutions People +TEL:tel:(718)793-2920 +FN:Dale Marino +GENDER:F +N:Marino;Dale;;; +ADR:;;665 Bubbling Brook Trail;Chicago;IL;60687; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;1081 Rivard Parkway;Samson;AL;36477; +N:Haase;Delfina;;; +BDAY:19841221 +FN:Delfina Haase +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:M +ORG:Solutions Max Architecture +EMAIL:gail.huggins@ipsumfeugait.info +IMPP:sip:gail@sip.linphone.org +FN:Gail Huggins +NOTE:Lobortis aliquip te lorem eum at. +ADR:;;3702 Mer Rouge Parkway;Rushford;MN;55971; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Molly Mackay +TEL:tel:(660)981-4122 +BDAY:19641207 +EMAIL:m.mackay@exerciipsum.gov +ORG:Telecom Software South +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:teddy.mabry@utwisialiquam.us +ORG:Federated Industries Vision +TEL:tel:(405)551-5837 +FN:Teddy Mabry +IMPP:sip:teddy@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(702)708-5533 +GENDER:O +IMPP:sip:geri@sip.linphone.org +BDAY:19640925 +EMAIL:geri@adaugue.eu +FN:Geri Olds +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Hendrerit ut eufeugiat zzril blandit odio ea dolore enim nulla. +EMAIL:abraham@facilisisduis.net +ORG:Design Architecture Federated +ADR:;;8423 Rowlock Trail;Doran;VA;24612; +FN:Abraham Kruse +IMPP:sip:abraham@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +ADR:;;9310 Bell Manor Trail;San Diego;CA;92176; +IMPP:sip:josiah@sip.linphone.org +FN:Josiah Dunne +N:Dunne;Josiah;;; +NOTE:Commodoconsequat minim lobortis zzril doloremagna ullamcorper illum eum euismod ea nislut delenitaugue. +EMAIL:josiah@elitsedexerci.eu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Eum esse veniamquis dolore duis molestie te. +GENDER:U +FN:Alberta William +IMPP:sip:alberta@sip.linphone.org +ADR:;;7710 Fox Fern Avenue;Detroit;MI;48288; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:corey.collier@nullavero.com +BDAY:19690813 +N:Collier;Corey;;; +GENDER:F +FN:Corey Collier +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Commodo nostrud enim nostrud vulputate ut. +ADR:;;2826 Mikeyair Avenue;Cloverport;KY;40111; +GENDER:N +N:Suggs;Germaine;;; +IMPP:sip:germaine@sip.linphone.org +FN:Germaine Suggs +TEL:tel:(580)461-1359 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Dignissim duis vel elitsed zzril in aliquip lorem iusto at hendrerit. +N:Blackman;Olivia;;; +GENDER:N +FN:Olivia Blackman +BDAY:19800410 +EMAIL:o.blackman@nibhaliquip.eu +ORG:Medicine Virtual +TEL:tel:(848)914-4661 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:d.mooney@minimexerci.net +ADR:;;8131 Green Twig Circle;Grand Lake Stream;ME;04637; +IMPP:sip:donald@sip.linphone.org +TEL:tel:(660)196-9482 +FN:Donald Mooney +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Erich Mcclung +N:Mcclung;Erich;;; +ORG:Telecom Source +TEL:tel:(337)275-3036 +GENDER:M +NOTE:Iriuredolor et elitsed in minim praesent illum duis. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:berniece.chinn@auguenislut.info +TEL:tel:(828)392-2752 +N:Chinn;Berniece;;; +FN:Berniece Chinn +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Venture East Virtual +EMAIL:m.guffey@autemblandit.gov +NOTE:Eros duis tation in blandit invulputate. +N:Guffey;Mary;;; +ADR:;;6327 Quarry Street;Shreveport;LA;71162; +FN:Mary Guffey +GENDER:O +IMPP:sip:mary@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:collin.randall@nislet.tv +IMPP:sip:collin@sip.linphone.org +BDAY:19601226 +FN:Collin Randall +NOTE:Nulla qui nulla illum exerci tincidunt. +ORG:Medicine Federated Industries +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;6124 Havershire Cove;Wilsey;KS;66873; +IMPP:sip:lynda@sip.linphone.org +FN:Lynda Marin +TEL:tel:(909)719-6894 +BDAY:19520323 +ORG:Galaxy Technology Venture +EMAIL:l.marin@essezzril.edu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(928)171-2203 +FN:Otis Nevarez +IMPP:sip:otis@sip.linphone.org +NOTE:Ut vero velit diam nonummy dolore lorem suscipit ea qui. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Qui duis ea ea vero eros delenitaugue autem ea tationullamcorper eros. +BDAY:19920324 +ORG:Frontier Hardware +N:Hardaway;Mabel;;; +IMPP:sip:mabel@sip.linphone.org +ADR:;;9493 Corporate Edge Circle;Albuquerque;NM;87106; +EMAIL:mabel.hardaway@autemtation.tv +TEL:tel:(904)898-8335 +FN:Mabel Hardaway +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Jacqueline Donley +ADR:;;7981 Rowan Trail;Harrisburg;PA;17104; +N:Donley;Jacqueline;;; +BDAY:19370803 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Hollingsworth;Gale;;; +EMAIL:gale.hollingsworth@amette.gov +FN:Gale Hollingsworth +GENDER:F +ADR:;;4267 Donnybrook Cove;Kennewick;WA;99338; +BDAY:19580312 +IMPP:sip:gale@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;268 Bobwood Drive;Garner;NC;27529; +ORG:Analysis Industries +FN:Myrtis Townes +EMAIL:myrtis.townes@delenitblandit.tv +N:Townes;Myrtis;;; +GENDER:N +BDAY:19940712 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(605)466-6346 +BDAY:19930708 +FN:Marcella Fairley +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Roger Person +ADR:;;518 Walworth Trail;Rowena;SD;57056; +EMAIL:roger@adipiscingvelit.gov +ORG:Star General +N:Person;Roger;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Nulla dolore autem dolor tincidunt. +FN:Marguerite Veal +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Findley;Danette;;; +FN:Danette Findley +ADR:;;1770 Rowan Parkway;Dalton;MN;56324; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Source Internet +FN:Haydee Fernandez +BDAY:19680114 +ADR:;;2795 Lost Meadow Street;Kingston;OK;73439; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +NOTE:Nostrud duis eufeugiat eum erat duis. +ADR:;;1248 Maple Shadow Trail;Warbranch;KY;40874; +BDAY:19420615 +FN:Stacie Chilton +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(507)347-5872 +FN:Agustin Devito +NOTE:Commodoconsequat at ipsum in eros doloremagna luptatumzzril eum velit nostrud facilisi. +ADR:;;5770 Mchenry Cove;Mount Berry;GA;30149; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:debby@autemin.edu +ADR:;;2318 Hickory Post Parkway;Alief;TX;77411; +FN:Debby Edward +TEL:tel:(205)732-9224 +GENDER:N +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Stephen Cushman +N:Cushman;Stephen;;; +ORG:North South Alpha +GENDER:M +EMAIL:stephen@accumsaneros.gov +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +BDAY:19590517 +FN:Beatrice Herbert +EMAIL:b.herbert@nullaodio.net +ORG:Graphics Consulting Network +IMPP:sip:beatrice@sip.linphone.org +N:Herbert;Beatrice;;; +TEL:tel:(812)577-3221 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Facilisi ea eum at feugiat ut Utwisi consequat aliquip. +N:Roden;Leslie;;; +EMAIL:leslie@facilisiconsequatvel.eu +FN:Leslie Roden +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +BDAY:19550125 +NOTE:Feugait et diam consectetuer. +FN:Stacy Dew +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;7616 Fleetwood Place Cove;Centerville;IN;47330; +ORG:Data Digital Graphics +FN:Alexandra Fite +BDAY:19680804 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(773)156-2480 +FN:Howard Thorne +BDAY:19940307 +NOTE:Facilisis autem dolor hendrerit etaccumsan feugiat doloremagna duis facilisis duis dignissim. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;3620 Green Twig Trail;West Sacramento;CA;95799; +FN:Harris Anglin +IMPP:sip:harris@sip.linphone.org +ORG:North General Direct +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +FN:Hollie Delong +ADR:;;8976 School Circle;Fairhaven;MA;02719; +TEL:tel:(857)725-4552 +N:Delong;Hollie;;; +BDAY:19420221 +IMPP:sip:hollie@sip.linphone.org +ORG:Hardware Data Vision +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Kelli Crews +IMPP:sip:kelli@sip.linphone.org +EMAIL:kelli@enimduis.us +ADR:;;2900 Edenfield Drive;San Diego;CA;92158; +TEL:tel:(207)472-3061 +BDAY:19900326 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Bobbie Rutherford +BDAY:19890218 +NOTE:Lobortis consequat doloremagna veniamquis ipsum volutpat molestie eros accumsan consectetuer. +N:Rutherford;Bobbie;;; +GENDER:U +ADR:;;9711 Baytown Avenue;Farmersburg;IN;47850; +ORG:Data Provider Medicine +EMAIL:b.rutherford@velfeugait.tv +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Electronics Analysis Provider +TEL:tel:(719)381-3190 +IMPP:sip:rodrigo@sip.linphone.org +ADR:;;3651 Greeley Way;Henderson;NY;13650; +GENDER:M +FN:Rodrigo Noe +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(610)972-3463 +NOTE:Autem vel iriure nonummy nulla dolore blandit iustoodio et. +GENDER:F +FN:Lauren Wilkins +ADR:;;4836 Farindon Lane;Madisonville;LA;70447; +EMAIL:l.wilkins@adipiscingwisi.tv +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Jewel Calvin +GENDER:U +BDAY:19871128 +IMPP:sip:jewel@sip.linphone.org +TEL:tel:(912)867-9631 +ADR:;;507 Akerswood Circle;South Bay;FL;33493; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Danelle Saunders +IMPP:sip:danelle@sip.linphone.org +EMAIL:danelle.saunders@euismodnibh.gov +GENDER:F +ADR:;;4474 Wolf Bend Drive;Campbellsburg;IN;47108; +BDAY:19661001 +N:Saunders;Danelle;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:w.stephen@veronislut.info +GENDER:U +TEL:tel:(405)719-5861 +FN:Werner Stephen +NOTE:Luptatumzzril minim amet ipsum. +ORG:Bell Construction Graphics +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Buckley;Claud;;; +ADR:;;3215 Towering Pines Way;Munden;KS;66959; +FN:Claud Buckley +EMAIL:claud.buckley@erosminim.gov +IMPP:sip:claud@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(206)732-9335 +IMPP:sip:allie@sip.linphone.org +EMAIL:allie.tuggle@laoreetwisi.gov +N:Tuggle;Allie;;; +GENDER:O +FN:Allie Tuggle +ORG:Consulting West Electronic +BDAY:19740722 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Bernie Story +N:Story;Bernie;;; +EMAIL:bernie@quiveniamquis.net +ORG:Speed Construction Future +GENDER:M +NOTE:Iustoodio enim tincidunt zzril nibh nislut delenitaugue nulla dignissim ex tation nisl eros. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Duis lorem commodoconsequat odio tation at. +ADR:;;6828 Whipper Trail;Surfside;CA;90743; +GENDER:O +FN:Jerald Lerma +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Dillon Brant +ORG:Alpha Net +ADR:;;5222 William Trail;Boston;MA;02215; +N:Brant;Dillon;;; +BDAY:19510214 +GENDER:N +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Dykes;Tara;;; +FN:Tara Dykes +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Phelps;Ambrose;;; +IMPP:sip:ambrose@sip.linphone.org +FN:Ambrose Phelps +TEL:tel:(979)371-2315 +ORG:General Vision +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Dorthy Khan +ORG:Application Network Vision +GENDER:N +IMPP:sip:dorthy@sip.linphone.org +N:Khan;Dorthy;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:michell@sip.linphone.org +TEL:tel:(202)412-4499 +NOTE:At suscipit etaccumsan nostrud enim accumsan luptatum. +FN:Michell Gates +EMAIL:michell.gates@dolornulla.tv +GENDER:F +ORG:Bell Star West +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Summer Irizarry +N:Irizarry;Summer;;; +IMPP:sip:summer@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Paige;Quinn;;; +FN:Quinn Paige +BDAY:19390802 +ORG:Industries North Contract +EMAIL:q.paige@nislutdignissim.net +TEL:tel:(907)194-8051 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;4962 Gray Ridge Drive;Linkwood;MD;21835; +ORG:West Future +IMPP:sip:sharonda@sip.linphone.org +FN:Sharonda Harness +NOTE:Commodo esse iriuredolor commodoconsequat qui luptatum ut feugait ut lobortis at. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Augue feugait dolor consequatvel aliquam augue et nulla wisi commodoconsequat. +IMPP:sip:forrest@sip.linphone.org +ORG:Atlantic General Alpha +FN:Forrest Crandall +TEL:tel:(276)307-2435 +BDAY:19431005 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(406)670-5686 +FN:Marianna Baskin +NOTE:Duis zzril ipsum nulla augue aliquam duis. +ADR:;;3759 Parade Trail;Winkelman;AZ;85292; +GENDER:O +BDAY:19881211 +IMPP:sip:marianna@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Rickey Rossi +TEL:tel:(845)779-9956 +EMAIL:rickey@facilisisin.net +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Berry Bird +TEL:tel:(719)856-8369 +GENDER:M +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Contract Digital Network +NOTE:Dolore nulla quis minim feugait duis autem nisl dolore feugiat feugait eros et. +IMPP:sip:valeria@sip.linphone.org +BDAY:19370417 +N:Quinlan;Valeria;;; +EMAIL:valeria.quinlan@consequatduis.info +FN:Valeria Quinlan +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(765)654-3290 +N:Magnuson;Milo;;; +ADR:;;5031 Hayley Avenue;Grouse Creek;UT;84313; +FN:Milo Magnuson +ORG:Medicine Source Galaxy +BDAY:19841203 +GENDER:M +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Jessie Withers +TEL:tel:(518)944-2660 +NOTE:Nulla facilisis ea euismod nislut vel dignissim etaccumsan. +ADR:;;1366 Riverwood Circle;Renault;IL;62279; +N:Withers;Jessie;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Suscipit consequatvel vero wisi odio suscipit aliquam. +TEL:tel:(937)120-2252 +FN:Bobby Beaudoin +N:Beaudoin;Bobby;;; +ORG:Consulting Network Construction +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:m.guthrie@nostrudtationullamcorper.tv +N:Guthrie;Mervin;;; +ORG:Studio West Virtual +FN:Mervin Guthrie +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:jim@sip.linphone.org +NOTE:Exerci praesent dolor dolore tation consequat nulla. +GENDER:N +ADR:;;1877 Gallery Trail;Waxahachie;TX;75168; +FN:Jim Vincent +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +FN:Vicki Dulaney +ADR:;;1373 Leighton Creek Cove;Old Ocean;TX;77463; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;5211 Conifer Parkway;Duffield;VA;24244; +EMAIL:g.rose@nislutnulla.eu +NOTE:Consequat blandit enim consequat feugait delenitaugue ex. +ORG:Universal Data Solutions +FN:Guadalupe Rose +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:orville@sip.linphone.org +FN:Orville Robert +N:Robert;Orville;;; +EMAIL:o.robert@laoreetblandit.info +ORG:Resource Resource +NOTE:Ea eu feugait feugait lorem nulla nulla eros aliquip velit hendrerit eufeugiat. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Ray;Walter;;; +IMPP:sip:walter@sip.linphone.org +FN:Walter Ray +ADR:;;8566 Norell Trail;Van Nuys;CA;91470; +EMAIL:w.ray@facilisisutwisi.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Tincidunt accumsan lorem aliquip. +FN:Elias Luther +N:Luther;Elias;;; +IMPP:sip:elias@sip.linphone.org +GENDER:M +ADR:;;2955 Bison Lane;Owensboro;KY;42304; +EMAIL:elias@dolorut.gov +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;4735 Oakland Circle;Sun City;FL;33586; +GENDER:O +FN:Corrie Patel +NOTE:Dolore vel nisl consequat. +EMAIL:c.patel@utwisiautem.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Odio nulla feugiat in in. +FN:Zenaida Cummings +TEL:tel:(931)607-8047 +ADR:;;3135 Oak Run Circle;Orange City;FL;32763; +BDAY:19670529 +EMAIL:zenaida.cummings@delenitqui.tv +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;322 Oak Hill Drive;Granville;NY;12832; +ORG:Alpha Architecture Solutions +IMPP:sip:maryann@sip.linphone.org +N:Hartley;Maryann;;; +TEL:tel:(516)866-4794 +FN:Maryann Hartley +EMAIL:maryann.hartley@nullaamet.edu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;4343 Wax Myrtle Street;Charles City;VA;23030; +FN:Erin Radford +NOTE:At tincidunt doloremagna suscipit commodo. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(304)762-5025 +EMAIL:stevie@doloremagnaminim.gov +ADR:;;7095 Meadow Creek Bridge Way;Chapel Hill;NC;27599; +FN:Stevie Lane +N:Lane;Stevie;;; +IMPP:sip:stevie@sip.linphone.org +ORG:Innovation Net Graphics +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;428 Harding Circle;Tenmile;OR;97481; +N:Saucedo;Kim;;; +FN:Kim Saucedo +IMPP:sip:kim@sip.linphone.org +NOTE:Enim vero dignissim ex. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Pitre;Lowell;;; +TEL:tel:(775)554-2877 +EMAIL:lowell@exenim.gov +FN:Lowell Pitre +GENDER:O +ADR:;;3266 Kimdale Lane;Clontarf;MN;56226; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Mahaffey;Ollie;;; +GENDER:F +FN:Ollie Mahaffey +NOTE:Et feugait aliquip veniam aliquip adipiscing iriuredolor dignissim etaccumsan consequat. +BDAY:19951230 +IMPP:sip:ollie@sip.linphone.org +TEL:tel:(980)513-4181 +EMAIL:ollie@etea.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:marcy@exex.gov +FN:Marcy Kerr +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Latasha Pearl +IMPP:sip:latasha@sip.linphone.org +GENDER:F +NOTE:Aliquip iriuredolor at eros consectetuer nulla duis Utwisi autem facilisi. +EMAIL:latasha.pearl@sitsit.edu +TEL:tel:(260)491-2055 +N:Pearl;Latasha;;; +ORG:Galaxy Innovation +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(605)973-7350 +FN:Camille Frasier +ADR:;;3444 Hayden Lane;Salt Point;NY;12578; +BDAY:19470808 +IMPP:sip:camille@sip.linphone.org +GENDER:F +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;7437 River Valley Cove;Walnutport;PA;18088; +EMAIL:jake@erosadipiscing.us +ORG:Adventure Star +FN:Jake Hand +BDAY:19840928 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:M +IMPP:sip:carroll@sip.linphone.org +TEL:tel:(773)723-4385 +N:Cathey;Carroll;;; +ORG:Internet Data Frontier +FN:Carroll Cathey +ADR:;;1767 Stonewyck Avenue;Key Biscayne;FL;33149; +EMAIL:carroll.cathey@etaccumsaninvulputate.com +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:gilberto@sip.linphone.org +N:Booker;Gilberto;;; +FN:Gilberto Booker +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(256)556-3304 +FN:Francis Loy +NOTE:Veniam facilisi suscipit nibh lobortis duis wisi facilisi ut illum vulputate consectetuer. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19940214 +ADR:;;6226 Washington Parkway;Detroit;MI;48228; +GENDER:N +EMAIL:d.deane@praesentesse.org +NOTE:Enim te hendrerit facilisi te molestie autem eros autem dolor blandit nostrud enim euismod. +FN:Delmer Deane +TEL:tel:(330)786-7248 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Suzan Power +ADR:;;1399 Thorncroft Circle;Lindsay;NE;68644; +N:Power;Suzan;;; +GENDER:N +NOTE:In elitsed duis nonummy feugait ad ut exerci ex facilisi luptatum facilisis. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:m.barth@blanditdolore.us +ADR:;;2953 Penrose Drive;Lahmansville;WV;26731; +TEL:tel:(661)749-9830 +ORG:Electronics Hardware +GENDER:F +FN:Marion Barth +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:nickolas.ammons@quisfeugait.us +FN:Nickolas Ammons +ORG:Bell Universal Provider +NOTE:Esse dolore dignissim ea qui eros iusto laoreet aliquip illum. +TEL:tel:(231)430-5467 +IMPP:sip:nickolas@sip.linphone.org +BDAY:19420922 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Verda Shoemaker +ORG:Network Adventure Net +N:Shoemaker;Verda;;; +NOTE:Nonummy esse odio iustoodio quis te facilisis vel suscipit. +TEL:tel:(920)592-8592 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19920205 +TEL:tel:(775)474-1876 +FN:Augusta Clouse +GENDER:F +EMAIL:augusta@adipiscingtincidunt.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +EMAIL:g.clouse@duisblandit.org +FN:Gustavo Clouse +ADR:;;7628 Carnton Circle;Riggins;ID;83549; +N:Clouse;Gustavo;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19450124 +FN:Latrice Forrester +ORG:Medicine Star Federated +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Caryn Holder +EMAIL:caryn.holder@veniamquisodio.edu +BDAY:19600125 +N:Holder;Caryn;;; +NOTE:Facilisis elitsed enim vel hendrerit duis dignissim iusto ut. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:jamal@sip.linphone.org +TEL:tel:(828)505-5856 +FN:Jamal Sun +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19431004 +ORG:Venture Design Future +NOTE:Illum feugiat eum velit esse commodo adipiscing ut eum aliquip tationullamcorper te consectetuer. +FN:Virginia Straub +N:Straub;Virginia;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Brant Oliva +TEL:tel:(469)493-6117 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Nulla facilisi et veniamquis vel ex ad feugiat eu facilisi. +GENDER:M +FN:Dante Clifford +TEL:tel:(718)915-7367 +ORG:Architecture Hill +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Vickey Langdon +ADR:;;1031 Wilkins Cove;Hallett;OK;74034; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(417)947-2514 +IMPP:sip:byron@sip.linphone.org +FN:Byron Tillman +ADR:;;2531 Saint Marys Street;Reading;PA;19604; +GENDER:M +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:corey.shively@laoreetiusto.edu +FN:Corey Shively +TEL:tel:(262)574-8446 +NOTE:Consectetuer in tationullamcorper luptatum luptatum eum feugait feugiat nulla iriuredolor. +IMPP:sip:corey@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Sample;Edwardo;;; +ORG:Frontier Star Frontier +BDAY:19880225 +GENDER:U +FN:Edwardo Sample +ADR:;;9095 Norcrest Drive;Elm Grove;LA;71051; +NOTE:Ut tationullamcorper vel et qui at dolore tationullamcorper in dolore. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +N:Ames;Pricilla;;; +BDAY:19881215 +TEL:tel:(510)883-5441 +ADR:;;3033 Bensonwood Way;Smithfield;VA;23431; +IMPP:sip:pricilla@sip.linphone.org +FN:Pricilla Ames +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Minim nulla duis euismod facilisis amet dolor nulla elitsed eros augue ad te. +IMPP:sip:mollie@sip.linphone.org +TEL:tel:(557)451-5439 +GENDER:N +FN:Mollie Wise +EMAIL:mollie.wise@nislveniam.us +N:Wise;Mollie;;; +BDAY:19720116 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:huey@nostrudhendrerit.tv +ADR:;;1418 Wethersfield Street;Dows;IA;50071; +TEL:tel:(503)627-1955 +BDAY:19601022 +NOTE:Dignissim eros iusto duis veniam augue delenitaugue. +FN:Huey Bolton +N:Bolton;Huey;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19480622 +ORG:Architecture Graphics +NOTE:Eu autem tation lobortis duis nulla molestie illum ad dolore. +FN:Randal Slater +TEL:tel:(920)395-8431 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:M +FN:Nathan Gaskins +NOTE:Commodo zzril lobortis iriure commodo suscipit. +ORG:Pacific Virtual +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Marguerite Flood +EMAIL:marguerite.flood@erossit.tv +IMPP:sip:marguerite@sip.linphone.org +ORG:West Net Architecture +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +FN:Madeline Terrill +N:Terrill;Madeline;;; +IMPP:sip:madeline@sip.linphone.org +ADR:;;5700 St Ives Circle;Houston;TX;77026; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;470 Isleton Trail;Redlake;MN;56671; +N:Chesser;Miranda;;; +FN:Miranda Chesser +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19690410 +TEL:tel:(408)788-1329 +GENDER:O +ADR:;;8947 Rutherford Circle;Glasgow;WV;25086; +FN:Leora Marra +IMPP:sip:leora@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(412)700-2271 +ORG:Frontier Pacific +EMAIL:j.rich@utwisieu.eu +GENDER:U +BDAY:19851210 +N:Rich;Jordon;;; +FN:Jordon Rich +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19890529 +FN:Yvonne Mcreynolds +TEL:tel:(907)483-5241 +GENDER:O +IMPP:sip:yvonne@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;6928 Jewell Circle;East Windsor;CT;06088; +GENDER:F +FN:Autumn Mejia +N:Mejia;Autumn;;; +IMPP:sip:autumn@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +IMPP:sip:verla@sip.linphone.org +ADR:;;5010 Hazel Avenue;Brian Head;UT;84719; +FN:Verla Skeen +N:Skeen;Verla;;; +EMAIL:verla@dignissimelitsed.eu +NOTE:Tincidunt facilisi lorem eu vero minim nulla. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Casey;Lauretta;;; +TEL:tel:(386)345-9605 +BDAY:19531213 +IMPP:sip:lauretta@sip.linphone.org +FN:Lauretta Casey +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:carey@veniamet.edu +ORG:South East Graphics +TEL:tel:(414)624-9448 +GENDER:M +FN:Carey Grossman +IMPP:sip:carey@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:U +BDAY:19750915 +EMAIL:d.alford@utquis.com +TEL:tel:(304)964-1689 +FN:Delfina Alford +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:emery@sip.linphone.org +EMAIL:emery.vanover@velcommodoconsequat.tv +ORG:Hardware Industries Future +TEL:tel:(619)343-5587 +ADR:;;1757 Oakgreen Cove;Sun Valley;CA;91352; +FN:Emery Vanover +N:Vanover;Emery;;; +BDAY:19970318 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:East West +TEL:tel:(304)946-2672 +FN:Brad Winkler +ADR:;;3409 Kallie Street;Philadelphia;PA;19125; +IMPP:sip:brad@sip.linphone.org +NOTE:Praesent dolore facilisis tationullamcorper ut Utwisi ea duis in. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;577 Falling Leaf Parkway;Sebring;FL;33871; +EMAIL:valerie@wisihendrerit.info +FN:Valerie Bonner +N:Bonner;Valerie;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Hill Pacific Future +ADR:;;6213 West Cove;Opelika;AL;36804; +IMPP:sip:natasha@sip.linphone.org +FN:Natasha Bey +NOTE:Diam iusto doloremagna facilisi esse ad dolore feugait minim illum adipiscing. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(330)791-3507 +FN:Sharla Shepherd +ADR:;;8437 Normandale Lane;Longmeadow;MA;01116; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Daniel Cortes +BDAY:19971218 +EMAIL:daniel@consectetuertation.tv +TEL:tel:(917)808-3404 +IMPP:sip:daniel@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19640120 +NOTE:Nulla laoreet et adipiscing amet amet facilisi nisl facilisi velit diam suscipit. +ADR:;;6040 May Woods Way;Willisburg;KY;40078; +FN:Wyatt Stine +GENDER:O +EMAIL:wyatt.stine@verosuscipit.info +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(831)362-5980 +BDAY:19481114 +IMPP:sip:oswaldo@sip.linphone.org +FN:Oswaldo Estes +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Jenny Peter +N:Peter;Jenny;;; +EMAIL:jenny@luptatumad.net +ORG:Interactive People +BDAY:19640306 +TEL:tel:(734)607-4010 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(715)508-5496 +EMAIL:sherry.mcclelland@dignissimut.gov +N:Mcclelland;Sherry;;; +ORG:Speed Bell +NOTE:Doloremagna blandit luptatumzzril vel minim blandit lorem eum facilisi vero hendrerit ut minim. +IMPP:sip:sherry@sip.linphone.org +FN:Sherry Mcclelland +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Technology Application Max +FN:Lyn Jay +TEL:tel:(912)586-2774 +EMAIL:lyn@euismoddolore.edu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Alvin Fogle +BDAY:19740422 +GENDER:M +ORG:Resource Solutions Architecture +NOTE:Aliquip nisl dignissim quis quis aliquam praesent iriure ea vulputate ex aliquip. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:ada@veroetaccumsan.gov +FN:Ada Monroe +IMPP:sip:ada@sip.linphone.org +BDAY:19940314 +ADR:;;4966 Hunters Hill Circle;Chautauqua;NY;14722; +N:Monroe;Ada;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Ramiro Rodman +BDAY:19920201 +ORG:Hill Galaxy East +GENDER:M +IMPP:sip:ramiro@sip.linphone.org +N:Rodman;Ramiro;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;5376 Hobbits Glen Lane;Benson;MN;56215; +FN:Lela Friday +N:Friday;Lela;;; +IMPP:sip:lela@sip.linphone.org +TEL:tel:(227)249-9236 +GENDER:U +ORG:Data Network +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(318)546-5395 +FN:Chiquita Neff +GENDER:U +BDAY:19590407 +N:Neff;Chiquita;;; +NOTE:Praesent facilisi lobortis etaccumsan feugiat ex minim. +EMAIL:chiquita@iriuredolorlorem.info +ADR:;;7034 Hillcrest Way;La Coste;TX;78039; +IMPP:sip:chiquita@sip.linphone.org +ORG:Advanced Analysis +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Aline Duggan +N:Duggan;Aline;;; +IMPP:sip:aline@sip.linphone.org +ADR:;;9577 Conner Cove;Madera;PA;16661; +TEL:tel:(203)459-3183 +NOTE:Etaccumsan vel molestie velit ad feugiat doloremagna hendrerit. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Rausch;Wade;;; +EMAIL:wade.rausch@eaqui.gov +GENDER:M +IMPP:sip:wade@sip.linphone.org +FN:Wade Rausch +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Alvina Randall +NOTE:Dignissim in iusto minim eu augue illum dolore feugiat facilisi luptatum lobortis invulputate. +BDAY:19790416 +N:Randall;Alvina;;; +EMAIL:alvina@autemesse.info +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(847)890-9178 +BDAY:19440524 +GENDER:F +IMPP:sip:may@sip.linphone.org +FN:May Mast +ORG:Net Consulting +ADR:;;2165 Green Forest Way;Chilton;TX;76632; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Interactive Resource +FN:Tasha Foust +NOTE:Ex erat nibh ad illum dolore vero luptatum quis luptatumzzril tation hendrerit nulla feugait. +TEL:tel:(310)689-7297 +EMAIL:tasha@adea.eu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:deloris@eaeum.com +FN:Deloris Everhart +N:Everhart;Deloris;;; +TEL:tel:(859)248-6910 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +BDAY:19381014 +FN:Stacy Patton +NOTE:Amet hendrerit laoreet nulla eufeugiat eros consectetuer sit velit iustoodio exerci tincidunt eum consectetuer. +N:Patton;Stacy;;; +TEL:tel:(612)728-9446 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;743 Melville Street;Toms River;NJ;08755; +ORG:Galaxy Application Universal +FN:Wally Bello +EMAIL:wally.bello@duisinvulputate.info +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Warden;Tommie;;; +FN:Tommie Warden +IMPP:sip:tommie@sip.linphone.org +TEL:tel:(304)873-2320 +ADR:;;7001 Heatherly Cove;Springfield;MN;56087; +BDAY:19420729 +GENDER:F +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:monika.eck@ametvulputate.info +FN:Monika Eck +N:Eck;Monika;;; +NOTE:Exerci consequat ut lobortis feugiat ut dolore velit hendrerit ut hendrerit luptatum hendrerit hendrerit. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Galaxy Future Construction +EMAIL:marcos.soares@aliquamdolore.net +FN:Marcos Soares +TEL:tel:(203)377-4143 +ADR:;;7347 Mimosa Tree Circle;Peoria;IL;61652; +IMPP:sip:marcos@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Alvaro Cope +ORG:Electronics Network Electronic +EMAIL:a.cope@hendreritpraesent.info +BDAY:19560702 +IMPP:sip:alvaro@sip.linphone.org +N:Cope;Alvaro;;; +GENDER:M +ADR:;;6949 Grove Avenue;Cambridge;OH;43725; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Ripley;Ralph;;; +TEL:tel:(978)881-6783 +GENDER:M +ADR:;;2441 Wyndhurst Cove;Dulac;LA;70353; +FN:Ralph Ripley +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Dolore eros illum ad aliquip eu enim exerci dolore autem iustoodio et iusto feugiat. +N:Bunnell;Ma;;; +ORG:Telecom Solutions +IMPP:sip:ma@sip.linphone.org +FN:Ma Bunnell +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Sidney Bosley +N:Bosley;Sidney;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Ea facilisi et duis suscipit facilisis esse. +ORG:Atlantic Net +EMAIL:m.pacheco@velitvel.net +FN:Mariana Pacheco +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +BDAY:19740210 +NOTE:Qui ex duis odio odio. +FN:Sonya Judkins +N:Judkins;Sonya;;; +ORG:Medicine Direct Adventure +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:corinne.ruffin@adaliquam.org +FN:Corinne Ruffin +BDAY:19500328 +NOTE:Et nostrud iusto vero nostrud eu suscipit eum iriure dolore vel minim. +ORG:Speed South Pacific +ADR:;;3628 Centre Oak Trail;Harvard;MA;01451; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(850)977-5416 +FN:Niki Lerma +EMAIL:niki@blanditerat.tv +ORG:Universal Direct +NOTE:Amet ut nisl consequat. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Amanda Blount +NOTE:Eum veniamquis ea invulputate illum commodo nibh eum dolor commodoconsequat velit vero. +ADR:;;4167 Rich Hill Lane;Shawnee Mission;KS;66282; +GENDER:F +ORG:Provider Building +BDAY:19590503 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(434)420-7284 +NOTE:Iusto lorem duis consequatvel suscipit consectetuer lorem. +EMAIL:kenny@invulputatepraesent.net +IMPP:sip:kenny@sip.linphone.org +GENDER:O +BDAY:19390210 +ORG:Star Solutions +FN:Kenny Patton +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Aliquip et autem et tationullamcorper duis diam iriuredolor molestie diam zzril. +ORG:Electronics Solutions General +FN:Carlton Lyles +EMAIL:c.lyles@nulladuis.edu +ADR:;;6114 Crestwyn Parkway;Acme;PA;15610; +BDAY:19691111 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Vision Analysis Net +TEL:tel:(858)444-6224 +EMAIL:cristy.stovall@nullaexerci.info +IMPP:sip:cristy@sip.linphone.org +FN:Cristy Stovall +NOTE:Suscipit illum delenit aliquam vero ea veniamquis te. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(661)271-2630 +GENDER:O +N:Novotny;Van;;; +NOTE:Ea in consectetuer veniam dignissim vel dolor facilisi praesent lobortis nislut augue veniamquis suscipit. +ADR:;;2144 Wilkins Cove;Westtown;NY;10998; +FN:Van Novotny +ORG:Federated Internet Internet +EMAIL:van.novotny@duisvel.gov +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;2369 Paragon Way;High Springs;FL;32655; +FN:Leilani Girard +GENDER:F +IMPP:sip:leilani@sip.linphone.org +N:Girard;Leilani;;; +NOTE:Qui veniamquis dignissim nulla zzril feugait luptatum lorem. +ORG:Contract South Net +BDAY:19640108 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Eastman;Tyson;;; +TEL:tel:(386)597-7238 +FN:Tyson Eastman +ORG:Hardware Net +IMPP:sip:tyson@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Vision Hardware Design +GENDER:U +FN:Lupe Nesmith +BDAY:19900901 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Solutions Atlantic Signal +FN:Maria Gunderson +BDAY:19541224 +NOTE:Qui et accumsan euismod tation ex delenit in exerci duis dolore molestie diam. +ADR:;;4092 Calumet Circle;New Orleans;LA;70139; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19390915 +N:Harman;Lesa;;; +TEL:tel:(952)799-8829 +GENDER:U +NOTE:Volutpat dolor eros vero. +FN:Lesa Harman +EMAIL:lesa@dignissimnislut.info +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:t.benge@nullautwisi.tv +N:Benge;Terry;;; +ADR:;;9882 Ottumwa Street;Jarales;NM;87023; +GENDER:F +IMPP:sip:terry@sip.linphone.org +FN:Terry Benge +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Jewell Nickel +GENDER:M +TEL:tel:(310)780-3255 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Mac Ritter +N:Ritter;Mac;;; +TEL:tel:(740)368-5881 +IMPP:sip:mac@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19860829 +IMPP:sip:riley@sip.linphone.org +FN:Riley Noble +GENDER:O +NOTE:Vero iriuredolor feugiat lobortis dolor veniamquis blandit in qui. +N:Noble;Riley;;; +ADR:;;8947 Hobbits Glen Circle;Joseph City;AZ;86032; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:pablo.trudeau@adlobortis.eu +IMPP:sip:pablo@sip.linphone.org +FN:Pablo Trudeau +ADR:;;6291 Brush Creek Trail;Hastings;NE;68902; +TEL:tel:(260)891-1300 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:sophia@sip.linphone.org +FN:Sophia High +ADR:;;725 Meadowview Circle;Layton;NJ;07851; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Martin Nall +GENDER:M +BDAY:19490406 +ADR:;;6183 Corporate Center Way;Louisville;KY;40221; +ORG:Source Interactive Source +NOTE:Qui feugiat exerci nislut amet suscipit Utwisi commodo vel autem nulla. +TEL:tel:(515)820-2997 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Source Virtual Hardware +FN:Tyrell Kerns +IMPP:sip:tyrell@sip.linphone.org +EMAIL:tyrell.kerns@suscipitexerci.com +ADR:;;6822 Brewers Street;La Mesa;NM;88044; +NOTE:Iriuredolor et esse dignissim. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Ramon;Clare;;; +ORG:Design Digital General +BDAY:19370227 +FN:Clare Ramon +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Aliquip enim vulputate feugait commodoconsequat. +ADR:;;6551 Everwood Street;Bridgewater;NJ;08807; +IMPP:sip:chanel@sip.linphone.org +FN:Chanel Willey +N:Willey;Chanel;;; +TEL:tel:(724)661-3666 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Demetria Neel +ORG:Advanced South Alpha +N:Neel;Demetria;;; +NOTE:Ipsum blandit in autem nonummy facilisi in quis erat. +BDAY:19970627 +IMPP:sip:demetria@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;4386 Thornwick Drive;Minden;LA;71058; +N:Nicholas;Wes;;; +TEL:tel:(505)286-4023 +ORG:Alpha Net +GENDER:M +BDAY:19930629 +EMAIL:w.nicholas@velitblandit.edu +IMPP:sip:wes@sip.linphone.org +FN:Wes Nicholas +NOTE:Vel dignissim te accumsan aliquip commodoconsequat Utwisi. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Dolore facilisi nulla blandit volutpat facilisi feugait nulla duis. +FN:Domenic Winters +EMAIL:domenic.winters@duisat.tv +GENDER:O +TEL:tel:(207)676-5318 +BDAY:19930607 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(248)453-6728 +EMAIL:s.schneider@inaliquip.us +FN:Silas Schneider +N:Schneider;Silas;;; +GENDER:O +IMPP:sip:silas@sip.linphone.org +NOTE:Duis autem ipsum qui amet nostrud nibh iusto qui erat velit commodo doloremagna. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +FN:Louisa Grace +ADR:;;2220 Jocelyn Way;Black;AL;36314; +TEL:tel:(651)381-1704 +IMPP:sip:louisa@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19670128 +GENDER:F +ORG:Adventure Technology +FN:Shiela Ricks +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;3071 Heatherbrook Circle;Austin;TX;78748; +IMPP:sip:toney@sip.linphone.org +FN:Toney Krauss +BDAY:19551107 +TEL:tel:(864)675-5041 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(660)772-3012 +GENDER:M +FN:Walton Slaton +BDAY:19351207 +IMPP:sip:walton@sip.linphone.org +NOTE:Aliquip consectetuer facilisi eum feugait nibh ut ipsum iusto nonummy invulputate ut. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Hebert;Rudolph;;; +IMPP:sip:rudolph@sip.linphone.org +FN:Rudolph Hebert +NOTE:Laoreet feugait in veniam elitsed iusto duis adipiscing te suscipit velit molestie at tation. +EMAIL:rudolph@utlaoreet.info +ORG:Venture Galaxy +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;5133 Morning Dove Trail;Lineboro;MD;21088; +GENDER:N +BDAY:19940730 +EMAIL:b.bostick@facilisisconsequat.us +FN:Bruno Bostick +IMPP:sip:bruno@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +FN:Sammy Mahon +IMPP:sip:sammy@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +ORG:West Galaxy Interactive +IMPP:sip:christi@sip.linphone.org +BDAY:19371219 +EMAIL:c.gill@adipiscingeufeugiat.net +FN:Christi Gill +N:Gill;Christi;;; +ADR:;;2104 Stonewyck Lane;Potomac;MD;20854; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Rubye Muhammad +N:Muhammad;Rubye;;; +ORG:Federated Telecom +NOTE:In commodo invulputate iusto veniam eros vel dolore elitsed suscipit. +EMAIL:r.muhammad@velblandit.edu +GENDER:O +TEL:tel:(424)783-2218 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Daniel Bruns +TEL:tel:(239)613-7508 +GENDER:U +IMPP:sip:daniel@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:peter.gonsalves@exad.tv +FN:Peter Gonsalves +TEL:tel:(571)773-3394 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Carrol Shuler +IMPP:sip:carrol@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Rey Appleton +EMAIL:rey.appleton@autemnulla.gov +ADR:;;1621 Oxboro Cove;Sturgis;MI;49091; +IMPP:sip:rey@sip.linphone.org +GENDER:M +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Michal Nunez +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:collin@indignissim.info +FN:Collin Busch +N:Busch;Collin;;; +NOTE:Etaccumsan eum tationullamcorper te exerci luptatum. +IMPP:sip:collin@sip.linphone.org +BDAY:19750618 +ORG:Max Interactive General +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(918)656-4581 +IMPP:sip:jim@sip.linphone.org +BDAY:19800313 +NOTE:Lobortis feugait ex delenitaugue veniam delenitaugue facilisi facilisis duis ut dolore hendrerit dignissim vero. +FN:Jim Beaver +GENDER:O +N:Beaver;Jim;;; +ORG:Systems Hardware Software +EMAIL:jim@dolorediam.com +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:g.ostrander@facilisisfacilisis.gov +TEL:tel:(210)868-5445 +ORG:Innovation Provider Internet +GENDER:M +ADR:;;3274 Wilkins Drive;Ellabell;GA;31308; +FN:Glen Ostrander +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19660131 +GENDER:U +EMAIL:a.galbraith@aliquipaliquip.eu +FN:Arlen Galbraith +ORG:Systems Analysis Net +IMPP:sip:arlen@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Darcy Houck +ORG:Solutions Design +ADR:;;4209 Elk Run Street;Morristown;NJ;07963; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:jillian.lam@utetaccumsan.edu +NOTE:Quis molestie duis tationullamcorper suscipit. +FN:Jillian Lam +N:Lam;Jillian;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19480708 +FN:Bettye Sorrell +TEL:tel:(870)422-3359 +N:Sorrell;Bettye;;; +GENDER:N +NOTE:Aliquip eros velit vero. +IMPP:sip:bettye@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Cheney;Wally;;; +ADR:;;6166 Haseley Drive;Ingleside;TX;78362; +FN:Wally Cheney +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Research Industries +FN:Jospeh Beyer +NOTE:Dolor delenit commodoconsequat velit sit adipiscing et odio. +IMPP:sip:jospeh@sip.linphone.org +N:Beyer;Jospeh;;; +BDAY:19660131 +ADR:;;9777 Valley Crest Street;Mapleton;ME;04757; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:M +BDAY:19670226 +IMPP:sip:heriberto@sip.linphone.org +ADR:;;8916 Danforth Street;French Village;MO;63036; +N:Roden;Heriberto;;; +FN:Heriberto Roden +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(225)603-8216 +FN:Maynard Eden +EMAIL:m.eden@praesentiriuredolor.us +GENDER:U +ADR:;;4059 Orchard Hill Trail;Ogden;UT;84415; +ORG:Vision Interactive +NOTE:Eum blandit facilisis luptatum nibh nulla praesent lobortis velit feugiat lobortis duis vel. +BDAY:19510723 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Keyes;Bryon;;; +EMAIL:bryon.keyes@feugaitdelenit.org +FN:Bryon Keyes +ADR:;;5727 Hapano Street;Little Rock;AR;72295; +ORG:Frontier Atlantic +NOTE:Aliquip at duis nulla lobortis vel consequat. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19790318 +FN:Michele Burkett +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:U +NOTE:Etaccumsan vel delenitaugue esse volutpat aliquip nonummy praesent exerci nibh qui Utwisi te. +IMPP:sip:tristan@sip.linphone.org +FN:Tristan Amador +ADR:;;4568 Walkwood Lane;Fleetwood;PA;19522; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:titus@enimut.us +BDAY:19380925 +NOTE:Wisi iustoodio nulla sit. +IMPP:sip:titus@sip.linphone.org +GENDER:M +FN:Titus Andrus +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Rosita Nettles +IMPP:sip:rosita@sip.linphone.org +ORG:Hill Star +ADR:;;2347 Chestnut Avenue;Bessemer City;NC;28016; +N:Nettles;Rosita;;; +TEL:tel:(808)226-3984 +BDAY:19850308 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:santos@sip.linphone.org +FN:Santos Hedrick +EMAIL:santos@dolorepraesent.gov +TEL:tel:(501)502-5766 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;6333 Sandy Lane;Spring Valley;IL;61362; +FN:Easter Erickson +N:Erickson;Easter;;; +GENDER:F +TEL:tel:(626)706-3992 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Nona Stinson +N:Stinson;Nona;;; +GENDER:O +TEL:tel:(470)249-8522 +ORG:Vision General +ADR:;;8049 Commercial Street;Sargent;NE;68874; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:c.ingraham@iustout.com +ADR:;;2114 Woodleaf Cove;Porterville;CA;93258; +FN:Chong Ingraham +ORG:Power West +TEL:tel:(859)364-7708 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Hooker;Amparo;;; +BDAY:19780308 +NOTE:Minim dignissim eum Utwisi praesent iusto. +FN:Amparo Hooker +EMAIL:a.hooker@aliquipvel.info +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:M +FN:Anton Olivarez +ORG:Federated Internet Design +ADR:;;3638 Beaux Bridge Circle;Sharpsville;PA;16150; +TEL:tel:(469)444-8222 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:nicolas@sip.linphone.org +EMAIL:nicolas.worley@dolorconsequat.org +ADR:;;8398 Long Oak Trail;Stevenson;CT;06491; +FN:Nicolas Worley +GENDER:M +ORG:Construction Alpha Vision +NOTE:Feugiat exerci te minim. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:M +ADR:;;8811 Poplar Way;Conway;NH;03818; +TEL:tel:(773)568-5105 +FN:Scotty Vogt +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Speed Data +FN:Avery Prater +GENDER:N +BDAY:19470416 +N:Prater;Avery;;; +TEL:tel:(630)907-7067 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Industries Advanced Building +FN:Gwendolyn Abreu +BDAY:19390308 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(717)793-7719 +FN:Jeremiah Barton +GENDER:O +ADR:;;4299 Green Forest Circle;Macon;GA;31208; +BDAY:19680103 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(916)693-9508 +ORG:Pacific Telecom Alpha +FN:Jeromy Myrick +IMPP:sip:jeromy@sip.linphone.org +NOTE:Facilisi esse zzril invulputate wisi qui laoreet ullamcorper delenit commodo dolore euismod in. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Signal Hill Federated +ADR:;;3129 Hawksprings Trail;Waldport;OR;97394; +EMAIL:noe.weis@teautem.gov +FN:Noe Weis +IMPP:sip:noe@sip.linphone.org +BDAY:19450614 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:West Galaxy Adventure +BDAY:19580408 +ADR:;;5679 Somerset Cove;Brookston;TX;75421; +TEL:tel:(401)122-4169 +FN:Orville Whitehead +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;2460 Matisse Way;Ingold;NC;28446; +FN:Delfina Alvarez +GENDER:N +ORG:Net Advanced Building +TEL:tel:(574)622-6569 +EMAIL:delfina.alvarez@molestieeros.net +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Drummond;Jana;;; +NOTE:Ipsum luptatum consequat aliquam invulputate nulla diam dolore iusto quis dolore amet. +BDAY:19371108 +IMPP:sip:jana@sip.linphone.org +ORG:Federated Architecture Alpha +FN:Jana Drummond +GENDER:U +EMAIL:jana.drummond@accumsanaliquam.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19460901 +FN:Doyle Delgado +ADR:;;9711 Mchenry Way;Micro;NC;27555; +GENDER:M +TEL:tel:(702)231-4317 +ORG:Application Signal Medicine +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Odessa Shipman +ORG:People Contract +GENDER:O +TEL:tel:(573)929-2084 +ADR:;;7255 Durley Drive;Blue Point;NY;11715; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Marie Brand +EMAIL:marie@facilisimolestie.com +ADR:;;4112 Val Verde Drive;Minturn;SC;29573; +GENDER:F +TEL:tel:(703)584-6907 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Aileen Tovar +ADR:;;7079 Park Ridge Lane;Locust Fork;AL;35097; +BDAY:19500527 +EMAIL:aileen@praesentautem.info +GENDER:U +TEL:tel:(563)897-6866 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Analysis Max Graphics +ADR:;;5421 Grenville Street;Pleasanton;CA;94588; +BDAY:19470627 +IMPP:sip:gillian@sip.linphone.org +FN:Gillian Mcginnis +NOTE:Praesent illum aliquip et autem iustoodio hendrerit consequat nibh consequatvel facilisi. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:cara@veroerat.net +FN:Cara Mcneil +ORG:Net Data Industries +NOTE:Iustoodio consequat ullamcorper esse feugiat aliquip tincidunt illum feugait ea adipiscing. +IMPP:sip:cara@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Fredric Grayson +NOTE:Delenitaugue vel duis dolore illum veniamquis augue exerci quis eu vel delenitaugue. +ADR:;;991 Oak Manor Trail;Vernon;IL;62892; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Ivy Langdon +BDAY:19750322 +TEL:tel:(803)210-8297 +GENDER:F +ADR:;;4160 Meadow Wood Trail;New Vienna;IA;52065; +NOTE:In at nonummy facilisi nulla nostrud feugiat. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +TEL:tel:(630)529-3506 +ORG:Power Net +BDAY:19951029 +FN:Lemuel Mcgriff +EMAIL:lemuel.mcgriff@molestieet.net +N:Mcgriff;Lemuel;;; +NOTE:Odio aliquip ut esse ex in dignissim etaccumsan diam. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:s.chamberlain@elitsedin.gov +ADR:;;7010 Saint Marys Lane;Rock Springs;WI;53961; +NOTE:Sit accumsan velit augue dolore ea et nulla et et velit et praesent commodo. +FN:Sharla Chamberlain +BDAY:19510711 +ORG:Bell General +IMPP:sip:sharla@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Net Adventure North +EMAIL:donny.townsend@atwisi.eu +GENDER:M +ADR:;;7276 Foster Dale Drive;Rivervale;AR;72377; +IMPP:sip:donny@sip.linphone.org +FN:Donny Townsend +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Delenitaugue euismod dolore delenit nostrud iriure sit ut. +ORG:Construction Source Vision +IMPP:sip:leta@sip.linphone.org +GENDER:N +BDAY:19670524 +FN:Leta Kirk +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;6679 Havenhill Drive;Young America;MN;55557; +TEL:tel:(352)569-5498 +EMAIL:j.cameron@feugaitnibh.com +FN:Johnie Cameron +IMPP:sip:johnie@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:garrett@sip.linphone.org +ADR:;;9628 Bridge Forest Trail;Atlanta;GA;30392; +NOTE:Dolore facilisis praesent ut ipsum nibh delenitaugue facilisi lobortis ut nostrud nisl et diam. +TEL:tel:(323)557-2825 +FN:Garrett Peachey +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:edythe@sip.linphone.org +FN:Edythe Dougherty +BDAY:19730501 +N:Dougherty;Edythe;;; +ADR:;;3485 Tully Trail;Ocala;FL;34479; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;3495 Orchard Grove Avenue;Morgan Hill;CA;95038; +IMPP:sip:lacey@sip.linphone.org +FN:Lacey Hargett +GENDER:O +EMAIL:l.hargett@loremconsequat.us +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Fawn Albright +GENDER:O +EMAIL:fawn.albright@hendreritdolor.info +ORG:Federated Medicine Application +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19740811 +ORG:Pacific Industries +FN:Justine Alfaro +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19530304 +EMAIL:issac.coburn@utfacilisis.com +NOTE:Suscipit feugait enim suscipit. +ADR:;;2231 Regents Avenue;Soper;OK;74759; +FN:Issac Coburn +ORG:Consulting Application People +IMPP:sip:issac@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Desmond Kraft +NOTE:Nulla elitsed et volutpat autem consectetuer dolor feugait luptatumzzril odio minim zzril laoreet aliquip. +BDAY:19670606 +ORG:Atlantic East West +EMAIL:d.kraft@elitsedvel.tv +TEL:tel:(315)771-8545 +IMPP:sip:desmond@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Brittany Helms +N:Helms;Brittany;;; +NOTE:Nulla autem suscipit ullamcorper illum minim vel tincidunt consequat hendrerit minim. +GENDER:U +IMPP:sip:brittany@sip.linphone.org +EMAIL:brittany@utwisiqui.net +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Bo Bickford +BDAY:19370318 +NOTE:Dolor nibh in blandit et feugait aliquam velit iusto. +ADR:;;9662 Western Parkway;Banks;ID;83602; +ORG:Bell Venture +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:tanya@sip.linphone.org +ORG:North Resource Virtual +ADR:;;8305 Robin Parkway;Matoaka;WV;24736; +TEL:tel:(703)268-5308 +N:Montenegro;Tanya;;; +EMAIL:t.montenegro@dolorenulla.net +FN:Tanya Montenegro +NOTE:Consequat sit ullamcorper suscipit nulla feugiat nulla. +BDAY:19960623 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Leila Mcclanahan +ADR:;;5183 Everett Cove;Atlanta;GA;30334; +ORG:Systems Electronic Building +N:Mcclanahan;Leila;;; +EMAIL:leila.mcclanahan@veroaliquip.info +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +ADR:;;7083 Innsbruck Trail;Saint Petersburg;FL;33709; +TEL:tel:(530)822-4399 +NOTE:Consequatvel erat ut dignissim augue delenit nulla feugiat wisi lorem. +FN:Marlene Rosenberg +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Network Research +NOTE:Dolore exerci nibh iriuredolor commodoconsequat esse lorem ut autem sit praesent. +FN:Andres Houston +GENDER:M +ADR:;;413 Malcolm Cove;Pompano Beach;FL;33077; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +NOTE:Ad blandit adipiscing in hendrerit enim esse hendrerit. +ORG:Digital Universal +TEL:tel:(419)814-9532 +EMAIL:s.dallas@dolorillum.info +FN:Stacy Dallas +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Feugait accumsan luptatumzzril et. +ADR:;;3284 Toro Circle;Eek;AK;99578; +FN:Rafaela Sledge +GENDER:O +TEL:tel:(412)993-6896 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:M +FN:Jackson Mckay +NOTE:Eum ad tationullamcorper praesent duis suscipit zzril invulputate facilisi esse. +N:Mckay;Jackson;;; +EMAIL:j.mckay@odioautem.tv +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Canady;Moses;;; +IMPP:sip:moses@sip.linphone.org +GENDER:N +FN:Moses Canady +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Eros te blandit ut. +IMPP:sip:isaias@sip.linphone.org +FN:Isaias Dowdell +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(515)290-7997 +FN:Esperanza Carlson +NOTE:Hendrerit ut facilisi in nulla at iustoodio ad luptatumzzril nisl wisi. +IMPP:sip:esperanza@sip.linphone.org +ORG:Max East +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(408)227-8737 +N:Oneill;Jospeh;;; +FN:Jospeh Oneill +EMAIL:j.oneill@tationhendrerit.tv +ORG:Studio Solutions +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:stephenie@sip.linphone.org +FN:Stephenie Redmon +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Williams;Adelaide;;; +EMAIL:a.williams@hendreritexerci.info +NOTE:Dolore ex iusto enim hendrerit eum ut veniam minim facilisi tationullamcorper eros. +IMPP:sip:adelaide@sip.linphone.org +BDAY:19431012 +FN:Adelaide Williams +ADR:;;8665 Laurinburg Street;Chambersburg;PA;17201; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Kate Stitt +NOTE:Dolor dolore veniamquis autem ut consequat nulla ex. +TEL:tel:(541)659-6119 +ADR:;;4988 Huntcliff Avenue;Plainfield;NJ;07062; +EMAIL:kate@molestiedolore.edu +N:Stitt;Kate;;; +GENDER:N +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(559)830-3541 +FN:Zoe Tang +IMPP:sip:zoe@sip.linphone.org +NOTE:Te delenit lobortis dolore esse etaccumsan nislut etaccumsan wisi nulla delenitaugue veniamquis te. +ORG:Resource East Future +ADR:;;3096 River Bend Cove;Garfield;NJ;07026; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Lindsey Reardon +N:Reardon;Lindsey;;; +EMAIL:l.reardon@minimexerci.com +BDAY:19690805 +IMPP:sip:lindsey@sip.linphone.org +ADR:;;2343 Rainbow Street;Tacoma;WA;98447; +NOTE:Invulputate hendrerit duis consequat. +TEL:tel:(480)482-1632 +ORG:Virtual Innovation +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Tremblay;Eusebio;;; +NOTE:In autem consectetuer lobortis. +EMAIL:eusebio@nostruddignissim.info +BDAY:19850207 +FN:Eusebio Tremblay +TEL:tel:(304)195-4577 +IMPP:sip:eusebio@sip.linphone.org +ORG:People General Network +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Adventure Architecture +GENDER:N +BDAY:19380309 +FN:Andra Gary +ADR:;;3697 Liberty Circle;Sunset;ME;04683; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Solutions Source Hill +ADR:;;1312 Oakes Way;Success;AR;72470; +GENDER:O +IMPP:sip:oswaldo@sip.linphone.org +EMAIL:oswaldo.hopson@eumnulla.eu +N:Hopson;Oswaldo;;; +TEL:tel:(317)700-4847 +NOTE:Feugiat hendrerit vero dolor vel ut vero duis molestie diam vero iriuredolor enim. +FN:Oswaldo Hopson +BDAY:19970517 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Conyers;Maudie;;; +GENDER:O +IMPP:sip:maudie@sip.linphone.org +FN:Maudie Conyers +TEL:tel:(864)681-5903 +ADR:;;6590 Winchester Trail;Docena;AL;35060; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Tation nulla nulla veniamquis ut volutpat feugiat consectetuer facilisis at delenitaugue hendrerit. +FN:Shauna Chaney +IMPP:sip:shauna@sip.linphone.org +GENDER:F +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19900924 +ORG:Frontier Interactive Network +FN:Marissa Vergara +N:Vergara;Marissa;;; +EMAIL:marissa.vergara@duisvel.eu +ADR:;;2249 Barons Drive;Manchester;MN;56064; +GENDER:U +NOTE:Dignissim illum hendrerit molestie in esse consectetuer doloremagna delenitaugue iriuredolor et nostrud ex. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:faustino@enimluptatumzzril.tv +FN:Faustino Dover +ADR:;;849 River Heights Drive;Widnoon;PA;16261; +ORG:Star General South +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:williams@sip.linphone.org +NOTE:Iustoodio nisl nislut amet velit nulla velit suscipit commodo lobortis. +N:Holley;Williams;;; +TEL:tel:(202)628-6388 +FN:Williams Holley +EMAIL:williams@doloreautem.eu +ADR:;;3448 Victoria Lane;Pleasant Lake;MI;49272; +ORG:Application Electronic Contract +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Consulting Atlantic +FN:Lillie Redmon +NOTE:Iusto diam iustoodio commodo commodoconsequat esse exerci consequatvel nulla nisl doloremagna ut dolore in. +GENDER:F +TEL:tel:(518)394-1947 +EMAIL:lillie.redmon@tinciduntinvulputate.info +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19370730 +FN:Mohammed Paulson +TEL:tel:(619)979-9169 +NOTE:Luptatum facilisi laoreet delenit esse delenitaugue amet eum Utwisi nulla euismod ea. +EMAIL:mohammed.paulson@nullacommodoconsequat.eu +ORG:Frontier Solutions West +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Taylor Sullivan +BDAY:19640911 +ORG:Provider Consulting Research +EMAIL:taylor@iriureet.us +NOTE:Consequat te ut enim ad ut duis nislut nulla doloremagna. +N:Sullivan;Taylor;;; +TEL:tel:(304)407-4653 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:George Herrington +ORG:Building Application Omega +BDAY:19881001 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:U +N:Erwin;Christina;;; +ADR:;;9992 Brownleaf Parkway;Pecks Mill;WV;25547; +FN:Christina Erwin +BDAY:19360113 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Neil Gilliam +TEL:tel:(682)676-1647 +EMAIL:neil@dolordolore.edu +ADR:;;2007 Paddock Way;West Hills;CA;91307; +NOTE:Iriure nulla commodoconsequat in iusto ullamcorper esse nulla dolore velit qui ea. +GENDER:M +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;3886 Greeley Way;Morrowville;KS;66958; +FN:Hugo Sandlin +BDAY:19661120 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Gerald Saenz +ORG:Omega People West +BDAY:19661006 +TEL:tel:(412)607-9819 +NOTE:Iustoodio nibh laoreet eu in elitsed qui quis delenitaugue esse. +GENDER:N +EMAIL:g.saenz@eatincidunt.info +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Eufeugiat suscipit feugait autem iriure qui vel minim veniam diam blandit. +FN:Carlton Rector +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Shirley;Evan;;; +GENDER:N +BDAY:19371024 +FN:Evan Shirley +IMPP:sip:evan@sip.linphone.org +ORG:Galaxy Advanced Network +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Steve Ferry +NOTE:At etaccumsan ipsum praesent illum wisi. +TEL:tel:(213)364-2534 +GENDER:U +ORG:Innovation Studio Technology +EMAIL:s.ferry@etaccumsanmolestie.tv +IMPP:sip:steve@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +FN:Joe Delacruz +ORG:Architecture Resource Electronic +NOTE:Facilisis etaccumsan ut aliquam. +EMAIL:joe.delacruz@suscipitminim.edu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:alecia@sip.linphone.org +BDAY:19880105 +FN:Alecia Gillis +N:Gillis;Alecia;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Graig Hawk +NOTE:Dignissim volutpat eufeugiat velit vero. +IMPP:sip:graig@sip.linphone.org +TEL:tel:(443)472-6334 +ORG:Net Vision Frontier +N:Hawk;Graig;;; +BDAY:19910708 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:guillermo@sip.linphone.org +GENDER:N +NOTE:Vel facilisi velit vel vulputate vel feugiat in elitsed dignissim velit nonummy vel commodoconsequat. +FN:Guillermo Hines +N:Hines;Guillermo;;; +BDAY:19360628 +ADR:;;7003 Osman Way;Alachua;FL;32615; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;1643 Peacan Circle;Branford;FL;32008; +N:Wise;Darin;;; +BDAY:19910416 +FN:Darin Wise +NOTE:Nostrud at quis adipiscing vel adipiscing adipiscing nulla dolore te hendrerit. +TEL:tel:(563)617-3028 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:d.kaminski@consectetueririure.tv +FN:Dewey Kaminski +GENDER:M +BDAY:19420102 +N:Kaminski;Dewey;;; +IMPP:sip:dewey@sip.linphone.org +ADR:;;4782 Kingsride Cove;Tibbie;AL;36583; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Interactive Telecom Architecture +TEL:tel:(706)348-7118 +GENDER:O +FN:Kevin Hutson +ADR:;;5470 Hazel Circle;Cincinnati;OH;45237; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:gale@sip.linphone.org +N:Folse;Gale;;; +ORG:Resource Internet +FN:Gale Folse +EMAIL:g.folse@nullain.org +BDAY:19930804 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +N:Lockwood;Rafaela;;; +FN:Rafaela Lockwood +TEL:tel:(980)368-1453 +ORG:Internet Star +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:alaina.ochoa@euismodaugue.tv +GENDER:N +FN:Alaina Ochoa +ORG:Electronic Hill Hardware +IMPP:sip:alaina@sip.linphone.org +BDAY:19350907 +NOTE:Nisl luptatum ullamcorper aliquip laoreet wisi aliquip ad velit. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Ut eum lorem hendrerit consequat molestie. +GENDER:U +FN:Stanford Zink +ADR:;;2798 Corporate Gardens Trail;Rago;KS;67128; +EMAIL:stanford@quifacilisi.com +IMPP:sip:stanford@sip.linphone.org +ORG:Alpha Source Solutions +BDAY:19370514 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Jarrett Eubanks +ORG:Virtual Digital People +EMAIL:jarrett@etvel.org +TEL:tel:(312)748-5625 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Black;Mason;;; +FN:Mason Black +BDAY:19820920 +GENDER:N +TEL:tel:(608)922-3041 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;6405 Sawyer Way;Lankin;ND;58250; +FN:Michell Cummins +N:Cummins;Michell;;; +GENDER:F +ORG:Adventure Atlantic +IMPP:sip:michell@sip.linphone.org +TEL:tel:(956)773-1500 +NOTE:Aliquip molestie duis amet nibh doloremagna suscipit eros. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Orlando;Emil;;; +ADR:;;4499 Poplar Estates Lane;Junction City;CA;96048; +FN:Emil Orlando +ORG:Building Software East +BDAY:19970401 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Farrow;Burt;;; +ADR:;;3932 Quant Circle;Charleston;WV;25314; +FN:Burt Farrow +EMAIL:b.farrow@eate.eu +TEL:tel:(973)156-5614 +IMPP:sip:burt@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Building Architecture +BDAY:19820616 +EMAIL:l.dougherty@iriuredoloraliquip.edu +FN:Louis Dougherty +NOTE:Nulla illum erat facilisi quis hendrerit illum nulla aliquip velit suscipit luptatumzzril amet velit. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;9568 Riverview Street;Rogersville;MO;65742; +BDAY:19721126 +ORG:Frontier Alpha +TEL:tel:(580)352-6590 +N:Saavedra;Teresita;;; +FN:Teresita Saavedra +NOTE:Autem nislut ex invulputate duis consequatvel. +EMAIL:t.saavedra@doloreipsum.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:z.numbers@dignissimea.com +GENDER:F +FN:Zoe Numbers +BDAY:19530127 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Denny;Keneth;;; +TEL:tel:(660)402-4120 +FN:Keneth Denny +GENDER:M +ADR:;;2746 Gershwin Drive;Quincy;OH;43343; +BDAY:19481031 +ORG:Atlantic Pacific Architecture +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;5133 Riverwind Drive;West Columbia;WV;25287; +FN:Addie Harden +EMAIL:a.harden@nullaqui.org +IMPP:sip:addie@sip.linphone.org +GENDER:O +ORG:Electronic East Advanced +NOTE:Eros luptatum sit tationullamcorper ad erat dignissim. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19890313 +FN:Isidro Ashton +ORG:Electronics Provider +TEL:tel:(917)331-7907 +GENDER:U +NOTE:Esse eum vel invulputate sit eros. +EMAIL:isidro@veldolore.edu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:rob.sheehan@tationconsequatvel.gov +FN:Rob Sheehan +GENDER:U +TEL:tel:(435)962-9596 +ORG:General Digital +IMPP:sip:rob@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:shanda.barraza@praesentesse.gov +FN:Shanda Barraza +TEL:tel:(215)283-5508 +GENDER:F +ORG:Star South Atlantic +ADR:;;3957 Willowbend Trail;Denver;CO;80237; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:douglas@sip.linphone.org +NOTE:Dolore duis exerci vero nostrud enim consectetuer. +FN:Douglas Neuman +BDAY:19500410 +ORG:Power Net Telecom +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Solutions Star +EMAIL:f.harman@eumconsequat.us +FN:Felipe Harman +N:Harman;Felipe;;; +IMPP:sip:felipe@sip.linphone.org +ADR:;;6861 Poplar Drive;Whitehall;MI;49461; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Quis facilisis elitsed autem tationullamcorper lobortis ullamcorper. +FN:Loyd Zielinski +EMAIL:l.zielinski@consequatvelzzril.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19720506 +FN:Perry Abraham +ORG:Adventure Construction Contract +ADR:;;75 Main Cove;Gulfport;MS;39506; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Sonja Boss +N:Boss;Sonja;;; +TEL:tel:(878)517-6710 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:gregory.pritchett@esseexerci.us +FN:Gregory Pritchett +ORG:Electronics Architecture +TEL:tel:(408)965-9886 +N:Pritchett;Gregory;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Valerie Kelleher +NOTE:Commodoconsequat consectetuer Utwisi dolore dolore ipsum qui feugait delenitaugue vel molestie exerci hendrerit. +TEL:tel:(989)492-9404 +ADR:;;5632 Woodbend Cove;Monterey;CA;93944; +GENDER:U +N:Kelleher;Valerie;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Christin Burnette +BDAY:19761120 +NOTE:Commodoconsequat in duis exerci delenit exerci esse aliquip hendrerit velit ut ut. +N:Burnette;Christin;;; +GENDER:F +ORG:Telecom Network Research +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(269)883-1327 +FN:Roman Tamayo +N:Tamayo;Roman;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(469)141-8991 +GENDER:U +BDAY:19771021 +FN:Willis Naylor +N:Naylor;Willis;;; +EMAIL:willis@consequatvelenim.net +ADR:;;224 Saint George Circle;Folsom;LA;70437; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(253)593-1510 +N:Dwyer;Genevieve;;; +FN:Genevieve Dwyer +EMAIL:g.dwyer@dignissimdolore.net +ADR:;;5176 Circleshade Lane;Emmaus;PA;18098; +GENDER:N +IMPP:sip:genevieve@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(620)612-3494 +EMAIL:annamarie.dugan@atdolore.info +GENDER:N +FN:Annamarie Dugan +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:johnson@aliquipduis.net +ORG:Construction Electronics Universal +BDAY:19921212 +FN:Johnson Brunson +IMPP:sip:johnson@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(612)181-7773 +IMPP:sip:vaughn@sip.linphone.org +N:Smiley;Vaughn;;; +BDAY:19811220 +EMAIL:v.smiley@etvel.net +FN:Vaughn Smiley +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Max Star Power +FN:Louisa Majors +IMPP:sip:louisa@sip.linphone.org +NOTE:Et vel aliquam et duis minim autem iusto. +N:Majors;Louisa;;; +ADR:;;8280 Otter Circle;Port Clinton;OH;43452; +GENDER:F +TEL:tel:(225)488-6239 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Lulu Lacey +EMAIL:l.lacey@consequatduis.org +GENDER:F +TEL:tel:(559)671-8385 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Ingram;Lee;;; +EMAIL:lee.ingram@molestienulla.org +NOTE:Ea consequatvel blandit ex consequat doloremagna ullamcorper dignissim delenit feugait esse nostrud. +GENDER:N +TEL:tel:(727)871-2405 +FN:Lee Ingram +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Mcmurray;Taylor;;; +EMAIL:taylor@addolor.gov +FN:Taylor Mcmurray +TEL:tel:(660)326-1555 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +IMPP:sip:lydia@sip.linphone.org +TEL:tel:(207)255-6135 +ORG:Omega Systems +ADR:;;8672 Heatherbrook Avenue;Hillview;KY;40129; +BDAY:19681221 +FN:Lydia Jeffrey +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:r.adler@quienim.com +NOTE:Facilisi duis vero adipiscing at accumsan enim. +BDAY:19890307 +GENDER:N +N:Adler;Rafaela;;; +FN:Rafaela Adler +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Hardy;Janis;;; +ADR:;;5182 Sycamore Avenue;Edroy;TX;78352; +FN:Janis Hardy +ORG:Building Electronic Data +EMAIL:j.hardy@tationet.info +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(215)513-3270 +GENDER:O +IMPP:sip:jake@sip.linphone.org +FN:Jake Krause +EMAIL:jake.krause@doloreduis.org +NOTE:Facilisi et eros dignissim duis at lorem dolore aliquam illum iriure. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Eufeugiat ut hendrerit vel luptatum iriuredolor nulla veniamquis dignissim luptatum iusto ad aliquip. +FN:Grady Killian +GENDER:O +BDAY:19641011 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:cletus.forrest@molestieodio.us +TEL:tel:(975)230-3679 +NOTE:Suscipit nulla dignissim iriuredolor delenitaugue dolore augue minim nulla nulla at blandit nulla. +ADR:;;1998 Oldridge Parkway;New Johnsonville;TN;37134; +FN:Cletus Forrest +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Reyna;Allan;;; +NOTE:In tincidunt aliquip aliquam. +TEL:tel:(518)585-3228 +FN:Allan Reyna +IMPP:sip:allan@sip.linphone.org +ORG:Medicine South Resource +GENDER:M +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Liz Horner +NOTE:Diam et illum zzril veniamquis consequat blandit aliquam facilisis et exerci at. +IMPP:sip:liz@sip.linphone.org +N:Horner;Liz;;; +TEL:tel:(424)458-3347 +ADR:;;996 Lofton Parkway;Walker;MO;64790; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19410903 +FN:Valentin Pitt +NOTE:Ut augue iustoodio facilisi nostrud adipiscing. +EMAIL:valentin@exblandit.com +IMPP:sip:valentin@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(434)114-7200 +NOTE:Feugait autem eum velit autem praesent vero duis illum at vero ad diam. +FN:Morgan Wayne +N:Wayne;Morgan;;; +EMAIL:m.wayne@feugaitea.org +BDAY:19580930 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19570726 +FN:Racheal Farias +ADR:;;2566 Falling Leaf Parkway;Wade;NC;28395; +N:Farias;Racheal;;; +EMAIL:racheal@eaquis.com +ORG:Construction Pacific +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Hal Hubbard +GENDER:N +ADR:;;7168 Jocelyn Trail;Burneyville;OK;73430; +N:Hubbard;Hal;;; +EMAIL:h.hubbard@diamquis.com +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:dusty@dolorfeugiat.net +FN:Dusty Helton +GENDER:M +NOTE:Aliquip eros molestie at eum ullamcorper duis eros ut veniam luptatum nulla. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Esteban Dew +EMAIL:e.dew@duislobortis.org +TEL:tel:(320)258-8117 +N:Dew;Esteban;;; +NOTE:Volutpat ut lobortis duis tincidunt. +ADR:;;7405 Oak Manor Circle;New Haven;CT;06504; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Design Resource +IMPP:sip:adell@sip.linphone.org +EMAIL:adell@wisite.eu +TEL:tel:(734)952-4085 +N:Godfrey;Adell;;; +NOTE:Nostrud exerci tincidunt nostrud zzril dolore velit esse nulla dolor aliquip duis tation minim. +FN:Adell Godfrey +ADR:;;979 Newberry Way;Cascadia;OR;97329; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Esse vel zzril tincidunt vero autem. +TEL:tel:(201)379-7518 +ORG:Data Data +FN:Burt Falk +IMPP:sip:burt@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Rees;Guy;;; +FN:Guy Rees +EMAIL:g.rees@facilisiste.tv +NOTE:Suscipit feugiat ut hendrerit lobortis. +ORG:Contract Vision +IMPP:sip:guy@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;129 Redwood Place Lane;Castanea;PA;17726; +N:Kee;Kaitlyn;;; +FN:Kaitlyn Kee +BDAY:19860613 +ORG:Virtual Federated +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(229)783-8723 +BDAY:19730818 +N:Golden;Sonia;;; +EMAIL:s.golden@loremhendrerit.net +FN:Sonia Golden +ADR:;;521 Rivercrest Parkway;Springfield;VA;22150; +GENDER:F +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Munn;Lyman;;; +TEL:tel:(978)839-1511 +FN:Lyman Munn +EMAIL:lyman@velitsuscipit.gov +BDAY:19650201 +NOTE:Duis nisl dolor illum autem nulla facilisis dolor velit invulputate nonummy in. +ADR:;;7326 Island Grove Avenue;Durant;FL;33530; +IMPP:sip:lyman@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Illum ipsum odio dolore Utwisi minim qui exerci in. +FN:Stacie Garvey +N:Garvey;Stacie;;; +IMPP:sip:stacie@sip.linphone.org +BDAY:19780819 +EMAIL:stacie.garvey@wisisit.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Greenlee;Rena;;; +BDAY:19641011 +ORG:Graphics South +GENDER:O +TEL:tel:(352)887-6426 +FN:Rena Greenlee +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Praesent praesent lorem minim aliquam ad suscipit feugait vulputate duis nislut. +N:Lanham;Chung;;; +FN:Chung Lanham +TEL:tel:(401)768-2075 +EMAIL:c.lanham@duiseufeugiat.com +ADR:;;5871 Meadowview Way;Stuyvesant Falls;NY;12174; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;3008 Osgood Lane;Milton;MA;02186; +ORG:Virtual East People +EMAIL:yong.gooding@feugaitodio.gov +NOTE:Qui feugait blandit illum veniam tationullamcorper vero. +FN:Yong Gooding +TEL:tel:(440)873-7428 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Lee Miner +NOTE:Ipsum vel aliquam lorem. +ADR:;;5131 Saddle Ridge Drive;Fitzgerald;GA;31750; +BDAY:19690222 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(573)251-9606 +BDAY:19620529 +FN:Cleveland Prentice +ORG:South East Frontier +NOTE:Iustoodio in aliquam hendrerit exerci nulla quis invulputate ipsum nonummy eros eum enim ex. +EMAIL:cleveland.prentice@facilisisin.tv +ADR:;;668 Brittmoore Circle;Marietta;GA;30006; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Jude Melton +ADR:;;7572 Webster Circle;Hammond;IN;46320; +EMAIL:jude.melton@erosexerci.edu +BDAY:19971106 +GENDER:M +NOTE:Illum et iusto illum consequat. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;1756 Park Street;Castaic;CA;91384; +EMAIL:shirley.mulligan@exeum.net +FN:Shirley Mulligan +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;2362 Brookside Drive;Severn;MD;21144; +IMPP:sip:shawna@sip.linphone.org +N:Abney;Shawna;;; +BDAY:19770217 +GENDER:U +FN:Shawna Abney +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Damon Kern +IMPP:sip:damon@sip.linphone.org +NOTE:Erat adipiscing ut commodo. +N:Kern;Damon;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Eros accumsan veniamquis in lobortis hendrerit nulla et molestie facilisi duis etaccumsan eros enim. +ADR:;;8852 Moss Tree Cove;Pompano Beach;FL;33076; +N:Blake;Gay;;; +FN:Gay Blake +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Annabelle Conley +GENDER:F +NOTE:Autem lobortis iriure sit iriuredolor exerci molestie iustoodio. +ADR:;;7284 Three Chimneys Lane;Faith;SD;57626; +ORG:East Future Provider +N:Conley;Annabelle;;; +TEL:tel:(214)948-9155 +BDAY:19930418 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Vision Speed Medicine +N:Viera;Guadalupe;;; +TEL:tel:(434)158-2604 +ADR:;;8271 Towne Street;Merrifield;MN;56465; +EMAIL:guadalupe@duisdolore.eu +FN:Guadalupe Viera +IMPP:sip:guadalupe@sip.linphone.org +NOTE:Hendrerit ea consequatvel eufeugiat esse enim enim velit sit eufeugiat esse. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(907)324-4930 +ORG:Consulting Building +FN:Burton Root +NOTE:Dolor esse nibh in dignissim velit augue feugait dolore lobortis veniam eum. +GENDER:M +ADR:;;2254 Driving Park Circle;Eagar;AZ;85925; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:North Alpha Galaxy +EMAIL:k.sellars@duiscommodo.edu +TEL:tel:(208)122-8564 +FN:Kathrine Sellars +N:Sellars;Kathrine;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:m.scribner@feugaitfacilisis.tv +NOTE:Delenitaugue enim aliquam feugait hendrerit consequatvel molestie enim eum quis illum. +FN:Misty Scribner +TEL:tel:(901)150-8913 +N:Scribner;Misty;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(623)969-4134 +FN:Amelia Slaughter +ORG:Industries Graphics +GENDER:O +EMAIL:amelia@dolorconsequat.info +N:Slaughter;Amelia;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19970808 +FN:Celia Briggs +N:Briggs;Celia;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Modesto Redd +NOTE:Nibh invulputate facilisis nulla nonummy et lorem tationullamcorper. +ORG:Max Vision Atlantic +EMAIL:m.redd@etaccumsanminim.gov +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:luciano@sip.linphone.org +GENDER:O +TEL:tel:(310)752-9001 +ORG:Provider Architecture Consulting +FN:Luciano Tijerina +NOTE:Vel blandit dolore in ut ex nonummy nulla erat nulla velit iriuredolor. +EMAIL:luciano.tijerina@veleum.eu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Keys;Mel;;; +NOTE:Qui minim nonummy suscipit amet in nislut ea consequat. +BDAY:19511010 +FN:Mel Keys +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;1468 Holcombe Parkway;Golden;TX;75444; +IMPP:sip:thelma@sip.linphone.org +ORG:Virtual Venture +N:Stegall;Thelma;;; +BDAY:19871216 +FN:Thelma Stegall +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;7303 Chadbourne Drive;Chester;IA;52134; +IMPP:sip:beryl@sip.linphone.org +ORG:Signal Speed Resource +FN:Beryl Conyers +BDAY:19861026 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(901)857-4470 +IMPP:sip:benita@sip.linphone.org +BDAY:19620319 +NOTE:Nislut vel exerci ex. +ADR:;;2525 Appaloosa Drive;Lindenhurst;NY;11757; +GENDER:O +FN:Benita Perry +N:Perry;Benita;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Mcnulty;Melvin;;; +BDAY:19830502 +ADR:;;4760 Abercrombie Avenue;Atlanta;GA;30333; +FN:Melvin Mcnulty +TEL:tel:(608)596-9204 +NOTE:Commodo autem enim ad. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;4409 Lakespur Avenue;Minter;AL;36761; +N:Talbot;Marilyn;;; +NOTE:Erat esse tationullamcorper minim dolore ullamcorper vero delenit feugait eum quis. +FN:Marilyn Talbot +GENDER:F +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Karol Chester +N:Chester;Karol;;; +NOTE:Tationullamcorper diam lobortis ut feugait hendrerit lobortis vero et autem augue illum et. +GENDER:O +BDAY:19560518 +ORG:Internet Federated Bell +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(557)790-9739 +EMAIL:m.church@nullaluptatum.edu +GENDER:F +N:Church;Meghan;;; +FN:Meghan Church +ORG:Hill Solutions Industries +NOTE:Et eum duis illum tincidunt eros consequatvel nibh veniam iriure suscipit dolore et te. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Verla Mccurry +ORG:Application Virtual Industries +ADR:;;3437 Corporate Gardens Drive;Tok;AK;99780; +N:Mccurry;Verla;;; +EMAIL:verla.mccurry@lobortisdolore.gov +BDAY:19840705 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:marylou@sip.linphone.org +GENDER:F +ORG:Virtual Electronic +BDAY:19630616 +FN:Marylou Dykes +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Iusto accumsan vero ipsum nostrud. +ADR:;;1256 Last Arrow Circle;Collinsville;OK;74021; +FN:Opal Lennon +EMAIL:opal@etaccumsanvel.info +N:Lennon;Opal;;; +TEL:tel:(406)576-4445 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Warner;Sandy;;; +ORG:Research Design +FN:Sandy Warner +TEL:tel:(520)844-7609 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Arlen Paradis +N:Paradis;Arlen;;; +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Van Grimm +GENDER:U +IMPP:sip:van@sip.linphone.org +TEL:tel:(515)747-1192 +EMAIL:v.grimm@veroveniamquis.tv +NOTE:Lobortis delenitaugue accumsan delenitaugue suscipit commodo nonummy vel dolor veniam. +BDAY:19741119 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Max Graphics Design +TEL:tel:(707)112-4401 +N:Preston;Velda;;; +ADR:;;5461 Thornbranch Cove;Artois;CA;95913; +IMPP:sip:velda@sip.linphone.org +FN:Velda Preston +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Ashley Wynne +N:Wynne;Ashley;;; +GENDER:U +NOTE:Dolor elitsed odio iusto hendrerit te. +BDAY:19540629 +TEL:tel:(276)236-9593 +EMAIL:a.wynne@tationmolestie.info +IMPP:sip:ashley@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Eu ad adipiscing duis consequat enim ut dolor commodo nostrud aliquip luptatumzzril luptatumzzril erat. +EMAIL:rodrigo.rutherford@eufeugiatminim.eu +TEL:tel:(952)245-5127 +ADR:;;245 Honey Hill Lane;Oyster Bay;NY;11771; +GENDER:U +FN:Rodrigo Rutherford +BDAY:19860109 +N:Rutherford;Rodrigo;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(870)322-9123 +EMAIL:neil@velblandit.edu +GENDER:N +N:Fuentes;Neil;;; +ADR:;;4743 Trowbridge Cove;Houston;TX;77047; +FN:Neil Fuentes +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:;Emery;;; +GENDER:M +EMAIL:emery@dolorein.org +FN:Emery +TEL:tel:(870)853-3824 +ADR:;;6635 Plantation Trail;Alpha;KY;42603; +BDAY:19940502 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Et illum ex duis adipiscing ut exerci dignissim. +FN:Cordell Somers +IMPP:sip:cordell@sip.linphone.org +TEL:tel:(310)942-8444 +BDAY:19390227 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19630617 +FN:Mac Clay +N:Clay;Mac;;; +ORG:Application Source South +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;6969 Hillcrest Cove;Carrie;KY;41725; +IMPP:sip:randall@sip.linphone.org +N:Rainey;Randall;;; +FN:Randall Rainey +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;5587 Twisted Oak Street;Tallevast;FL;34270; +BDAY:19421102 +NOTE:Dolore facilisis exerci dolor Utwisi at dignissim ipsum zzril qui. +EMAIL:mable@sitvulputate.net +FN:Mable Pardo +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Wilburn;Amos;;; +ORG:Alpha Direct Consulting +FN:Amos Wilburn +ADR:;;2315 Oasis Parkway;Tuscaloosa;AL;35486; +TEL:tel:(260)269-8276 +EMAIL:amos@aliquipiustoodio.com +BDAY:19890505 +IMPP:sip:amos@sip.linphone.org +NOTE:Dolor nislut vero vel suscipit hendrerit blandit vel. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Boris Scherer +TEL:tel:(207)986-9506 +N:Scherer;Boris;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:angelia@sip.linphone.org +FN:Angelia Bower +BDAY:19470416 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;4765 Lookout Avenue;Albany;NY;12207; +ORG:Max Future +NOTE:Duis ex elitsed autem nostrud enim sit hendrerit qui. +IMPP:sip:terrell@sip.linphone.org +GENDER:M +EMAIL:t.rhodes@tincidunttincidunt.org +FN:Terrell Rhodes +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Michel Cave +ORG:Max Adventure Telecom +EMAIL:michel@diamipsum.com +IMPP:sip:michel@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Shanna Hollis +IMPP:sip:shanna@sip.linphone.org +GENDER:F +ADR:;;3646 Old Post Drive;Virginia;MN;55777; +N:Hollis;Shanna;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Mayme Amato +GENDER:N +ORG:Internet Future Pacific +EMAIL:mayme.amato@aliquipin.com +TEL:tel:(913)186-4444 +NOTE:Velit lorem sit blandit consectetuer qui blandit consectetuer facilisis ipsum qui commodoconsequat exerci. +IMPP:sip:mayme@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Esse in aliquip consequat illum vero amet hendrerit iriuredolor blandit. +BDAY:19560225 +FN:Marva Bruns +TEL:tel:(585)661-3714 +IMPP:sip:marva@sip.linphone.org +GENDER:F +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Source Building Frontier +ADR:;;4216 Kahlden Circle;Alexander City;AL;35011; +FN:Jeana Morton +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19670526 +GENDER:O +NOTE:Exerci iusto veniamquis aliquip odio praesent hendrerit diam nonummy vero veniam nisl nulla vero. +FN:Ernie Her +TEL:tel:(603)849-1657 +IMPP:sip:ernie@sip.linphone.org +N:Her;Ernie;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;8582 Winter Oaks Lane;Greenwich;NY;12834; +TEL:tel:(256)341-8666 +FN:Pattie Barbee +IMPP:sip:pattie@sip.linphone.org +EMAIL:pattie.barbee@commodofacilisi.com +N:Barbee;Pattie;;; +GENDER:F +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Becky Ralph +TEL:tel:(865)776-8961 +N:Ralph;Becky;;; +GENDER:F +ORG:Building Architecture +ADR:;;9359 Winners Parkway;Utica;PA;16362; +NOTE:Invulputate lorem nulla etaccumsan delenitaugue tationullamcorper. +EMAIL:becky@eaminim.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:chanel.billups@facilisifeugait.gov +TEL:tel:(737)995-6995 +ADR:;;9976 Newberry Parkway;Fairburn;SD;57738; +IMPP:sip:chanel@sip.linphone.org +FN:Chanel Billups +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Timothy Odonnell +IMPP:sip:timothy@sip.linphone.org +TEL:tel:(812)695-7169 +NOTE:Vel molestie commodo blandit augue iustoodio in lorem feugait praesent eu dolore. +ADR:;;9822 Fairy Falls Way;Cayuga;ND;58013; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Burchett;Emmett;;; +GENDER:U +FN:Emmett Burchett +TEL:tel:(201)763-2408 +ADR:;;7139 Oakes Way;Raiford;FL;32083; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Industries Design +TEL:tel:(205)865-4863 +IMPP:sip:donna@sip.linphone.org +FN:Donna Mcneal +ADR:;;9802 Sea Smoke Lane;Edgard;LA;70049; +BDAY:19620716 +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Georgina Burton +ORG:Universal Speed North +BDAY:19741211 +GENDER:F +IMPP:sip:georgina@sip.linphone.org +EMAIL:georgina.burton@commodofacilisis.us +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(817)768-6456 +ORG:Interactive Resource +BDAY:19570123 +FN:Aimee Cano +GENDER:O +IMPP:sip:aimee@sip.linphone.org +ADR:;;9419 Eagle Ridge Avenue;Bergman;AR;72615; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +BDAY:19601114 +NOTE:Dignissim amet blandit luptatumzzril consequat invulputate facilisi consectetuer vero velit. +FN:Donny Cannon +EMAIL:d.cannon@doloremagnaautem.info +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:margret.howell@velvero.edu +TEL:tel:(479)632-9962 +BDAY:19430401 +FN:Margret Howell +N:Howell;Margret;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:candace.jean@velet.net +FN:Candace Jean +TEL:tel:(406)387-1185 +N:Jean;Candace;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;8046 Sandy Creek Drive;Hamilton;MT;59840; +FN:Hassan Houck +NOTE:Eu delenit dolor duis nibh dolore nulla delenitaugue eu eufeugiat odio consectetuer volutpat eros. +ORG:Hardware Construction Pacific +BDAY:19541018 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Chas Foltz +GENDER:U +N:Foltz;Chas;;; +ADR:;;7644 Patchester Drive;Arbela;MO;63432; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:fern@exdolore.edu +ADR:;;6339 Grove Lane;Meeteetse;WY;82433; +GENDER:N +FN:Fern Scribner +TEL:tel:(912)877-9311 +NOTE:Ex iusto illum dignissim duis delenit ipsum molestie autem veniamquis aliquam at suscipit. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:orville@sip.linphone.org +ADR:;;9785 Jermyn Parkway;Cressey;CA;95312; +N:Hackney;Orville;;; +ORG:Construction Future +FN:Orville Hackney +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Patricia Conaway +EMAIL:p.conaway@veldiam.edu +ORG:East North Internet +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +IMPP:sip:amy@sip.linphone.org +EMAIL:amy@velitin.us +ADR:;;5006 Gumleaf Trail;Cherokee;OK;73728; +N:Blakely;Amy;;; +FN:Amy Blakely +ORG:Atlantic East Resource +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19771103 +FN:Elias Irish +IMPP:sip:elias@sip.linphone.org +N:Irish;Elias;;; +EMAIL:elias.irish@inerat.com +TEL:tel:(317)269-2062 +ORG:Hill Source Hardware +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:w.vaughan@doloreodio.eu +ORG:Software Architecture +TEL:tel:(928)416-6136 +FN:Willa Vaughan +NOTE:Volutpat etaccumsan duis Utwisi ut exerci exerci. +N:Vaughan;Willa;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;2052 Northwestern Parkway;Kathleen;GA;31047; +TEL:tel:(561)726-8397 +BDAY:19680324 +FN:Jerald Speight +N:Speight;Jerald;;; +IMPP:sip:jerald@sip.linphone.org +EMAIL:jerald.speight@facilisisillum.tv +GENDER:N +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Nita Jeffery +N:Jeffery;Nita;;; +NOTE:Ad ea facilisis vero lobortis te in ut dolore nostrud duis iusto. +IMPP:sip:nita@sip.linphone.org +BDAY:19570504 +ORG:General Source Hill +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:justin@adipiscingdolore.org +BDAY:19640119 +FN:Justin Marquis +ORG:Construction Adventure Software +TEL:tel:(564)289-9380 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Bowers;Ivan;;; +TEL:tel:(260)400-7716 +BDAY:19390821 +ORG:Interactive Vision Electronic +EMAIL:ivan@etlorem.com +GENDER:N +FN:Ivan Bowers +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;6851 Thorene Circle;Fence;WI;54120; +FN:Mickey Alves +EMAIL:m.alves@exdolor.org +NOTE:Eu esse molestie in duis facilisis nonummy duis. +TEL:tel:(803)557-5328 +ORG:Solutions Solutions +GENDER:F +N:Alves;Mickey;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(865)907-4687 +N:Tibbs;Alphonso;;; +ORG:Galaxy Advanced +FN:Alphonso Tibbs +IMPP:sip:alphonso@sip.linphone.org +NOTE:Lorem augue ut in in autem ut. +EMAIL:a.tibbs@facilisisaliquip.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +EMAIL:desmond@facilisiesse.info +N:Ortiz;Desmond;;; +FN:Desmond Ortiz +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:lucas@sip.linphone.org +N:Clarkson;Lucas;;; +BDAY:19380112 +FN:Lucas Clarkson +EMAIL:lucas@aliquammolestie.tv +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19670822 +FN:Amanda Mcgill +NOTE:Exerci veniamquis vero at velit consequatvel blandit veniamquis at feugiat hendrerit blandit euismod. +GENDER:N +EMAIL:a.mcgill@commodotation.com +N:Mcgill;Amanda;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Laoreet facilisis ut ut nostrud molestie in doloremagna esse invulputate nulla. +FN:Rachel Newman +BDAY:19840321 +ORG:Industries Graphics +ADR:;;1004 Cross Pike Trail;Satsuma;FL;32189; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(205)540-6396 +GENDER:N +N:Ulrich;Angelia;;; +FN:Angelia Ulrich +IMPP:sip:angelia@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Oshea;Wilson;;; +BDAY:19740228 +ADR:;;4893 Staples Circle;Packwood;IA;52580; +FN:Wilson Oshea +TEL:tel:(701)747-6762 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +EMAIL:kraig@dolorelitsed.info +FN:Kraig Valentin +IMPP:sip:kraig@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Nostrud delenitaugue tation vel praesent in dolore eros etaccumsan nostrud iustoodio odio ut. +N:Dykes;Vonda;;; +TEL:tel:(304)499-2940 +GENDER:F +ORG:East Solutions +FN:Vonda Dykes +BDAY:19810729 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(212)455-7126 +N:Forbes;Alisha;;; +GENDER:F +ORG:Alpha Galaxy +IMPP:sip:alisha@sip.linphone.org +EMAIL:a.forbes@feugaitvulputate.edu +ADR:;;2356 Londonderry Lane;Kansas City;MO;64130; +FN:Alisha Forbes +NOTE:Dolore invulputate enim invulputate in dolore lobortis lorem zzril nostrud autem euismod duis amet. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19600110 +ORG:Research Vision +FN:Wilbur Vieira +TEL:tel:(612)178-4929 +GENDER:M +N:Vieira;Wilbur;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:ahmed@sip.linphone.org +FN:Ahmed Mcnally +NOTE:Nostrud vel eufeugiat nulla dignissim eum erat molestie enim iriuredolor blandit tationullamcorper dolore vero. +GENDER:M +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Whitlow;Brandy;;; +IMPP:sip:brandy@sip.linphone.org +NOTE:Tation vel consequat eufeugiat nisl. +ORG:Atlantic Graphics Max +FN:Brandy Whitlow +ADR:;;7952 Olene Lane;Calico Rock;AR;72519; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Covington;Margery;;; +FN:Margery Covington +NOTE:Velit eros praesent eros erat blandit te duis. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Velez;Pat;;; +FN:Pat Velez +GENDER:N +BDAY:19690527 +EMAIL:pat@utduis.info +NOTE:Facilisi molestie eufeugiat etaccumsan duis wisi dolore commodoconsequat nulla consequat at nisl ut dolore. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:g.melendez@luptatumzzrilconsequatvel.us +NOTE:Facilisi vel ea lobortis enim tincidunt nulla qui diam elitsed feugait vulputate augue accumsan. +FN:Glenda Melendez +TEL:tel:(949)202-9819 +ORG:Analysis Construction +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:brigitte@sip.linphone.org +N:Griffin;Brigitte;;; +ORG:Design Net +FN:Brigitte Griffin +EMAIL:b.griffin@veroet.info +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Facilisi hendrerit exerci illum quis eu iusto blandit laoreet in dolore luptatum qui. +FN:Archie Gaston +BDAY:19920804 +IMPP:sip:archie@sip.linphone.org +N:Gaston;Archie;;; +EMAIL:a.gaston@erosnibh.net +TEL:tel:(540)688-8072 +GENDER:N +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Lakesha Zuniga +N:Zuniga;Lakesha;;; +NOTE:Molestie duis iriuredolor aliquip vel accumsan ea tationullamcorper commodoconsequat qui minim iusto esse et. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Odio aliquip delenitaugue amet nonummy dignissim. +EMAIL:callie.thornton@doloresse.com +N:Thornton;Callie;;; +GENDER:N +FN:Callie Thornton +IMPP:sip:callie@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:luis@sip.linphone.org +NOTE:Feugiat dolor exerci nulla. +EMAIL:l.cato@adutwisi.info +GENDER:M +TEL:tel:(715)183-7862 +FN:Luis Cato +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Alpha Internet Universal +ADR:;;7007 Newgate Cove;Wheatland;WY;82201; +FN:Randi Reinhart +EMAIL:r.reinhart@dolorefeugait.tv +IMPP:sip:randi@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Lorena Gant +NOTE:Et in commodo te blandit ullamcorper. +TEL:tel:(806)228-8784 +ORG:Star Vision +IMPP:sip:lorena@sip.linphone.org +ADR:;;2770 Donnington Circle;Bradenton;FL;34212; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Max Studio Electronic +EMAIL:colleen@nostruddolore.net +IMPP:sip:colleen@sip.linphone.org +ADR:;;2325 Barryknoll Way;Glenwood;MD;21738; +FN:Colleen Fajardo +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Jason Moniz +ORG:Hardware Architecture Atlantic +N:Moniz;Jason;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:guy@sip.linphone.org +BDAY:19901224 +GENDER:U +ORG:Vision Building Technology +EMAIL:guy.aponte@diammolestie.org +FN:Guy Aponte +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;4421 Old Bridge Cove;Ludlow;PA;16333; +GENDER:N +NOTE:Ut dolor praesent eros at. +EMAIL:israel.darling@elitsedautem.eu +BDAY:19870624 +FN:Israel Darling +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(832)548-1347 +FN:Elaine Zeller +IMPP:sip:elaine@sip.linphone.org +N:Zeller;Elaine;;; +BDAY:19960312 +GENDER:O +NOTE:Vero exerci ut et eufeugiat enim illum facilisis iriure. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Provider Application Direct +IMPP:sip:tracie@sip.linphone.org +EMAIL:t.verdin@doloreut.org +FN:Tracie Verdin +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Cooks;Jesse;;; +FN:Jesse Cooks +GENDER:F +TEL:tel:(920)508-9584 +NOTE:Illum exerci molestie velit eum delenit enim te. +ADR:;;8998 Deerfield Way;Elizaville;NY;12523; +EMAIL:jesse.cooks@nullaodio.edu +ORG:Data Electronics Consulting +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Sebastian Freed +TEL:tel:(479)830-5833 +NOTE:Ipsum vel duis tation te nostrud. +ORG:Architecture Design +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:kayla@sip.linphone.org +TEL:tel:(818)306-5034 +BDAY:19680730 +GENDER:U +FN:Kayla Carnes +ADR:;;7300 Muir Avenue;Gregory;SD;57533; +N:Carnes;Kayla;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:hortencia@nislautem.info +IMPP:sip:hortencia@sip.linphone.org +NOTE:Accumsan ad at wisi wisi at vero illum vero laoreet. +ORG:Signal East West +GENDER:U +FN:Hortencia Reitz +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Quentin Steward +TEL:tel:(408)999-1140 +N:Steward;Quentin;;; +BDAY:19400209 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Euismod esse eufeugiat iustoodio. +BDAY:19960705 +GENDER:O +N:Moreau;Annmarie;;; +EMAIL:annmarie@eufacilisis.us +FN:Annmarie Moreau +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Francisco Beattie +ORG:Industries Bell Universal +NOTE:Accumsan te molestie feugiat nulla praesent esse amet diam minim te veniam odio. +N:Beattie;Francisco;;; +ADR:;;261 Aspen Pine Drive;Parsons;KS;67357; +BDAY:19591019 +TEL:tel:(478)745-3799 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:norberto@euillum.us +GENDER:O +ORG:Advanced Software +FN:Norberto Boggs +BDAY:19580213 +IMPP:sip:norberto@sip.linphone.org +N:Boggs;Norberto;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;2864 Millstone Lane;North Grosvenordale;CT;06255; +FN:Nellie Chavarria +NOTE:Dolore enim esse autem vero suscipit nulla luptatumzzril minim odio dolor nulla. +N:Chavarria;Nellie;;; +GENDER:F +TEL:tel:(785)350-8066 +BDAY:19480413 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(845)492-3976 +IMPP:sip:rosalyn@sip.linphone.org +NOTE:Dolore aliquam etaccumsan ut nisl illum veniam nulla sit facilisi lobortis. +FN:Rosalyn Rome +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:U +FN:Stanford Stpierre +ORG:Electronics Max Application +NOTE:Luptatumzzril ex molestie lobortis. +BDAY:19600526 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Dominic Carmichael +NOTE:Nostrud adipiscing nulla euismod tation ipsum autem dolore dolore vero nulla autem laoreet. +GENDER:O +BDAY:19550919 +TEL:tel:(281)322-1438 +ADR:;;3706 Heritage Street;Chataignier;LA;70524; +ORG:East Data Direct +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Dolore ipsum aliquam esse commodo feugait Utwisi ut aliquam wisi. +EMAIL:l.snell@veltation.us +FN:Lynette Snell +ORG:Digital Direct Architecture +N:Snell;Lynette;;; +GENDER:U +TEL:tel:(859)444-7118 +IMPP:sip:lynette@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Joann Bruce +IMPP:sip:joann@sip.linphone.org +NOTE:Tincidunt esse duis vero enim. +EMAIL:joann.bruce@tationut.net +ORG:Vision Source +N:Bruce;Joann;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Ut nislut duis aliquip ex consequatvel. +ORG:Telecom Industries North +GENDER:M +FN:Jermaine Cummins +N:Cummins;Jermaine;;; +IMPP:sip:jermaine@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Aliquip illum duis eros consequat. +N:Callaghan;Serena;;; +IMPP:sip:serena@sip.linphone.org +GENDER:U +ADR:;;1185 Osgood Circle;Roxana;KY;41848; +FN:Serena Callaghan +BDAY:19520419 +EMAIL:serena@nibhtincidunt.net +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:lillie@sip.linphone.org +N:Coyle;Lillie;;; +EMAIL:lillie.coyle@nislutdolore.edu +FN:Lillie Coyle +TEL:tel:(719)287-2284 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:benedict@sip.linphone.org +ADR:;;331 Lakemere Street;Orlando;FL;32898; +ORG:Research Industries +NOTE:Suscipit nisl molestie lobortis praesent enim odio. +FN:Benedict Warren +GENDER:M +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Laoreet in nostrud dolore ad laoreet quis etaccumsan dolore nostrud. +N:Geer;Janet;;; +EMAIL:janet.geer@exnonummy.eu +ADR:;;871 Stagecoach Lane;Caneyville;KY;42721; +IMPP:sip:janet@sip.linphone.org +FN:Janet Geer +BDAY:19880907 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Qui molestie nislut veniamquis et nulla commodoconsequat dignissim consequat ea velit vel et. +FN:Jonathon Heflin +N:Heflin;Jonathon;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Aliquip duis quis adipiscing eros luptatum praesent. +EMAIL:c.fabian@eaqui.gov +FN:Courtney Fabian +ADR:;;7972 Boom Trail;Baton Rouge;LA;70835; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +NOTE:Ullamcorper dolore dolore facilisi te aliquam nulla dolore wisi nulla nislut. +EMAIL:oleta.stanfield@consequateuismod.tv +TEL:tel:(561)919-6933 +FN:Oleta Stanfield +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:catina@sip.linphone.org +FN:Catina Whalen +ADR:;;2606 Winding Creek Trail;Goldbond;VA;24094; +N:Whalen;Catina;;; +EMAIL:catina.whalen@aliquipaliquam.org +NOTE:Euismod amet consequat dolor erat molestie nibh suscipit diam feugiat. +TEL:tel:(228)896-4249 +GENDER:F +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Sit Utwisi aliquam facilisi blandit at nulla augue nostrud et nostrud consequatvel. +TEL:tel:(610)250-3736 +FN:Horacio Cheatham +ADR:;;8173 Bobwood Street;Le Roy;KS;66857; +GENDER:M +ORG:Medicine Hardware +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Nonummy iusto velit eufeugiat sit odio dolore. +EMAIL:a.legg@hendreritvel.us +ADR:;;5845 Parker Cove;Engelhard;NC;27824; +TEL:tel:(975)762-3484 +FN:Ashleigh Legg +BDAY:19680224 +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19650102 +FN:Julius Spears +ORG:Bell Network Galaxy +N:Spears;Julius;;; +ADR:;;559 Cornuta Circle;North Haven;ME;04853; +EMAIL:julius@nullaminim.edu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Contract Vision +EMAIL:sid.linn@laoreetiustoodio.net +FN:Sid Linn +NOTE:Ea feugait ad enim. +IMPP:sip:sid@sip.linphone.org +GENDER:O +ADR:;;1609 Lake Avenue;West Des Moines;IA;50266; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Curtis Winslow +NOTE:Nulla nostrud ut consectetuer at qui invulputate odio in etaccumsan duis ad velit eros. +TEL:tel:(256)426-8196 +N:Winslow;Curtis;;; +GENDER:M +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;2006 Fox Creek Circle;Vicksburg;MS;39182; +GENDER:N +TEL:tel:(283)293-6758 +FN:Amie Hinton +EMAIL:amie@dolorehendrerit.gov +BDAY:19820722 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;2296 Riverview Drive;Murchison;TX;75778; +EMAIL:paulette@augueea.tv +GENDER:U +FN:Paulette Lemons +ORG:Signal Solutions Design +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19661007 +ADR:;;6591 Oakville Circle;Old Hickory;TN;37138; +N:Galarza;Daron;;; +NOTE:Autem blandit doloremagna ex Utwisi ex ut nulla Utwisi lobortis eu. +FN:Daron Galarza +ORG:Star Frontier +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +EMAIL:charlie@commodoconsequatautem.org +ADR:;;2645 Southmoore Avenue;Kansas City;KS;66106; +NOTE:Autem esse praesent illum at duis ut zzril eufeugiat odio vero molestie erat. +FN:Charlie Easley +TEL:tel:(270)848-9739 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:aurelio@tationullamcorperpraesent.us +NOTE:Et ullamcorper commodo dolor dolor nisl iriure et amet. +FN:Aurelio Bruns +IMPP:sip:aurelio@sip.linphone.org +N:Bruns;Aurelio;;; +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19530817 +ADR:;;1813 Hill Creek Cove;Wesco;MO;65586; +NOTE:Vulputate nulla feugait nonummy suscipit illum vel dolor diam enim hendrerit blandit. +FN:Deana Good +EMAIL:deana.good@tationiriuredolor.tv +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:drew@sip.linphone.org +TEL:tel:(775)506-6318 +BDAY:19810625 +EMAIL:d.gonsalves@elitsedat.tv +ADR:;;8682 Chestnut Way;Shiloh;GA;31826; +FN:Drew Gonsalves +N:Gonsalves;Drew;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19700822 +FN:Belva Doolittle +IMPP:sip:belva@sip.linphone.org +ORG:Venture Galaxy Medicine +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Workman;Bryon;;; +FN:Bryon Workman +EMAIL:bryon.workman@dignissimullamcorper.info +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19710419 +ADR:;;979 Staples Circle;Olympia;KY;40358; +FN:Orval Harrison +GENDER:M +ORG:Electronic Consulting Power +NOTE:Consectetuer duis vel delenit. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Booker Mouton +TEL:tel:(304)907-3686 +N:Mouton;Booker;;; +IMPP:sip:booker@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:gerald@sip.linphone.org +FN:Gerald Lafleur +ADR:;;9063 Bradford Parkway;Newberry;SC;29108; +TEL:tel:(315)532-7328 +ORG:Construction Architecture North +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Tia Hoyle +GENDER:F +EMAIL:tia.hoyle@enimdiam.gov +IMPP:sip:tia@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;9499 Heathstone Avenue;Lebanon;PA;17042; +FN:Bobbie Cardenas +GENDER:U +NOTE:Ut minim hendrerit iriure. +EMAIL:b.cardenas@molestieesse.edu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;2087 Pineridge Street;Miami;FL;33130; +IMPP:sip:janette@sip.linphone.org +EMAIL:janette.cromer@intation.eu +ORG:Virtual Star +BDAY:19570518 +FN:Janette Cromer +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19801207 +ADR:;;250 Jewell Cove;Altona;IL;61414; +FN:Anita Weatherford +N:Weatherford;Anita;;; +IMPP:sip:anita@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Pasquale Rodriquez +EMAIL:pasquale@dignissimat.us +ORG:Architecture Application Internet +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:roscoe.wray@essepraesent.tv +TEL:tel:(315)643-3592 +BDAY:19461224 +FN:Roscoe Wray +N:Wray;Roscoe;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Abraham;Paul;;; +FN:Paul Abraham +GENDER:U +EMAIL:p.abraham@indelenit.com +ADR:;;3891 Anchorage Cove;Casselberry;FL;32707; +BDAY:19600621 +TEL:tel:(508)192-7791 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(283)551-8207 +FN:Alvaro Robbins +BDAY:19930701 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19500925 +FN:Rosie Fawcett +ADR:;;4383 Cane Creek Street;Treichlers;PA;18086; +IMPP:sip:rosie@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19940203 +FN:Catalina Haynes +TEL:tel:(207)315-9888 +GENDER:N +IMPP:sip:catalina@sip.linphone.org +NOTE:Suscipit doloremagna exerci illum illum molestie vero. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Amie Steward +NOTE:Facilisi tincidunt ullamcorper in dolore blandit duis molestie dolor praesent diam. +N:Steward;Amie;;; +IMPP:sip:amie@sip.linphone.org +ORG:Speed Electronics Network +BDAY:19791116 +ADR:;;528 Myrtle Lane;Los Indios;TX;78567; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:patty@sip.linphone.org +TEL:tel:(907)764-8263 +GENDER:F +BDAY:19520727 +FN:Patty Vanhorn +ADR:;;7814 Driftwood Street;Kent;AL;36045; +ORG:Electronics East Data +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:brooke@doloremagnavelit.tv +GENDER:N +ADR:;;2088 Danbury Parkway;Nada;TX;77460; +IMPP:sip:brooke@sip.linphone.org +NOTE:Consectetuer praesent exerci euismod at facilisi exerci. +FN:Brooke Alba +ORG:Systems Hardware +TEL:tel:(574)751-8739 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Luptatum odio suscipit ut zzril nulla dignissim erat qui eum praesent. +ORG:Vision Technology Digital +BDAY:19360420 +FN:Russ Chadwick +N:Chadwick;Russ;;; +IMPP:sip:russ@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Atlantic Signal Electronic +BDAY:19900112 +FN:Orval Rowley +ADR:;;7545 Jewell Way;Vernon;AL;35592; +NOTE:Velit zzril aliquam vulputate in nisl ut. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:christy.moulton@hendreritdignissim.eu +IMPP:sip:christy@sip.linphone.org +FN:Christy Moulton +NOTE:Nulla lobortis esse facilisis sit hendrerit vulputate autem nulla autem molestie sit. +BDAY:19841010 +ORG:Telecom Net Analysis +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Future Adventure +N:Jarman;Damien;;; +NOTE:Esse autem nulla ad nislut iriuredolor et aliquam aliquam. +FN:Damien Jarman +TEL:tel:(512)290-1765 +BDAY:19440108 +ADR:;;2760 Bent Creek Street;Tifton;GA;31793; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(914)996-3452 +ORG:Electronic Bell Vision +BDAY:19770703 +N:Hand;Jarrett;;; +IMPP:sip:jarrett@sip.linphone.org +EMAIL:j.hand@nislqui.org +NOTE:Iriure vero suscipit dolor ex vel invulputate etaccumsan enim praesent Utwisi. +FN:Jarrett Hand +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:jeff.wyatt@duisat.tv +ORG:Construction Frontier Advanced +ADR:;;8196 Centre Oak Parkway;Barnegat Light;NJ;08006; +FN:Jeff Wyatt +GENDER:M +NOTE:Feugait ad euismod vel sit. +N:Wyatt;Jeff;;; +IMPP:sip:jeff@sip.linphone.org +TEL:tel:(786)863-5178 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;4739 Kinderhill Drive;San Francisco;CA;94141; +FN:Gayla Lemus +TEL:tel:(562)801-3000 +EMAIL:g.lemus@euismodwisi.us +GENDER:F +ORG:Software Net +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Mel Whittaker +EMAIL:m.whittaker@consequatsuscipit.gov +IMPP:sip:mel@sip.linphone.org +ORG:Atlantic Interactive +ADR:;;8631 Heatherbrook Parkway;Springvale;ME;04083; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Industries Internet Building +IMPP:sip:hong@sip.linphone.org +ADR:;;1887 Stonewyck Trail;Altoona;AL;35952; +BDAY:19680110 +FN:Hong Mclendon +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Caleb Salgado +N:Salgado;Caleb;;; +GENDER:M +ADR:;;5691 Kickerillo Circle;Burlington;NJ;08016; +EMAIL:caleb.salgado@adduis.eu +ORG:East Frontier Network +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(918)824-6403 +IMPP:sip:jack@sip.linphone.org +FN:Jack Valdes +GENDER:M +ORG:Architecture Software +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:merry.woodson@eumconsequat.eu +BDAY:19870819 +FN:Merry Woodson +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Ea vulputate iusto te ex hendrerit iustoodio praesent. +EMAIL:jessie@lobortissuscipit.eu +GENDER:M +FN:Jessie Seaton +BDAY:19740423 +IMPP:sip:jessie@sip.linphone.org +N:Seaton;Jessie;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Alfredo Champagne +ADR:;;5956 Germantown Village Street;Warsaw;IL;62379; +EMAIL:alfredo@duisvelit.com +IMPP:sip:alfredo@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:julianne@sip.linphone.org +FN:Julianne Jordon +TEL:tel:(843)979-2054 +N:Jordon;Julianne;;; +EMAIL:j.jordon@inin.net +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Merry Poole +IMPP:sip:merry@sip.linphone.org +NOTE:Duis hendrerit velit et vel at feugait invulputate eu duis consequat. +EMAIL:merry@autemiusto.tv +ADR:;;9336 Mcclellan Lane;Austin;CO;81410; +N:Poole;Merry;;; +TEL:tel:(626)749-5600 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Yvonne Warfield +ORG:Data Solutions +BDAY:19781125 +GENDER:N +IMPP:sip:yvonne@sip.linphone.org +EMAIL:yvonne@autemetaccumsan.gov +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Gruber;Elia;;; +FN:Elia Gruber +ADR:;;836 Hobbits Glen Street;Tuskahoma;OK;74574; +EMAIL:e.gruber@commodoat.com +ORG:Max Source General +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:cristina.nealy@laoreetnostrud.com +ORG:Power West Application +TEL:tel:(319)940-6805 +IMPP:sip:cristina@sip.linphone.org +FN:Cristina Nealy +NOTE:Dolore enim lobortis laoreet. +ADR:;;840 Island Grove Street;Packwaukee;WI;53953; +GENDER:F +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(713)785-9554 +GENDER:O +ADR:;;4410 Quirt Way;Wenham;MA;01984; +N:Becker;Marlon;;; +IMPP:sip:marlon@sip.linphone.org +FN:Marlon Becker +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Rhett Lemay +BDAY:19940731 +EMAIL:rhett.lemay@iustoenim.edu +IMPP:sip:rhett@sip.linphone.org +ORG:Speed Solutions South +GENDER:M +TEL:tel:(901)447-7008 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Dolore diam molestie vel dignissim zzril qui veniamquis duis feugait vel in. +TEL:tel:(660)919-1575 +IMPP:sip:carol@sip.linphone.org +FN:Carol Eubanks +ADR:;;6789 Leaning Ash Parkway;Cedar Lake;MI;48812; +N:Eubanks;Carol;;; +EMAIL:carol@suscipitinvulputate.tv +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19790211 +N:Dupont;Ione;;; +EMAIL:i.dupont@nislvero.eu +GENDER:N +FN:Ione Dupont +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:U +IMPP:sip:mallory@sip.linphone.org +NOTE:Esse dignissim illum duis. +N:Pemberton;Mallory;;; +BDAY:19520526 +FN:Mallory Pemberton +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19940709 +FN:Bianca Chambers +ORG:Signal Pacific +N:Chambers;Bianca;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:carol.moriarty@autemdolore.eu +TEL:tel:(316)208-4060 +GENDER:N +IMPP:sip:carol@sip.linphone.org +ORG:Venture Contract +FN:Carol Moriarty +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(301)112-2744 +IMPP:sip:fritz@sip.linphone.org +GENDER:U +NOTE:Facilisis blandit laoreet ut te. +FN:Fritz Loper +EMAIL:fritz.loper@dignissimsit.org +N:Loper;Fritz;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Jorge Brito +BDAY:19630710 +ORG:Studio Software Analysis +N:Brito;Jorge;;; +EMAIL:jorge.brito@iriuredolorvulputate.info +ADR:;;1965 Legend Way;Smithfield;WV;26437; +TEL:tel:(564)240-6751 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Dolore autem luptatumzzril ea ex luptatum ut velit at lorem adipiscing commodo dolore. +FN:Bryan Pena +GENDER:O +N:Pena;Bryan;;; +ADR:;;3319 Soboda Cove;Houston;TX;77042; +EMAIL:bryan.pena@miniminvulputate.com +ORG:Graphics Federated North +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +FN:Tonja Pepper +NOTE:Te et blandit nonummy dolore dolor. +ADR:;;6395 Cordie Lee Parkway;East Sparta;OH;44626; +ORG:Hardware Innovation +BDAY:19900214 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:carmen@sip.linphone.org +FN:Carmen Mccorkle +NOTE:Invulputate facilisis Utwisi illum enim facilisis eufeugiat dolore. +GENDER:F +N:Mccorkle;Carmen;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:jeannine@sip.linphone.org +GENDER:O +FN:Jeannine Cintron +N:Cintron;Jeannine;;; +TEL:tel:(641)947-2136 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:jill@sip.linphone.org +EMAIL:jill@esseconsectetuer.tv +ORG:Industries Net +N:Rinehart;Jill;;; +BDAY:19650817 +FN:Jill Rinehart +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;7520 Corporate Center Drive;East Derry;NH;03041; +FN:Guadalupe Cuellar +NOTE:Vulputate delenitaugue lobortis accumsan aliquam dolore odio ullamcorper luptatumzzril delenit. +IMPP:sip:guadalupe@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:j.vest@feugiatdignissim.tv +ORG:Medicine Max Adventure +BDAY:19750923 +FN:Janice Vest +ADR:;;9645 Landfair Trail;Spencer;OK;73084; +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(631)935-6965 +NOTE:Eros feugiat nostrud ea eum ea. +ORG:Advanced Signal South +BDAY:19631102 +N:Meeker;Maudie;;; +FN:Maudie Meeker +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Vero in veniamquis et commodoconsequat te dignissim elitsed diam in nulla suscipit blandit et. +GENDER:U +FN:Joseph Brand +TEL:tel:(703)691-2199 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19451202 +EMAIL:v.whitten@dolornulla.edu +FN:Vance Whitten +N:Whitten;Vance;;; +GENDER:U +ADR:;;3921 Mayfield Lane;Cincinnati;OH;45230; +ORG:Internet Digital Construction +TEL:tel:(605)972-6400 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Bettis;Wm;;; +GENDER:U +FN:Wm Bettis +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Mia Cameron +ORG:Bell Venture Power +TEL:tel:(425)586-9243 +NOTE:Te hendrerit aliquip facilisis. +BDAY:19871021 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19381119 +FN:Shon Jay +IMPP:sip:shon@sip.linphone.org +N:Jay;Shon;;; +TEL:tel:(207)755-1935 +ADR:;;9051 West Trail;Outing;MN;56662; +GENDER:M +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Cartwright;Hannah;;; +ORG:Data Advanced Source +EMAIL:h.cartwright@eumvero.net +FN:Hannah Cartwright +NOTE:Wisi veniamquis nostrud facilisis facilisi eum ut vero iustoodio volutpat ipsum at minim iriuredolor. +TEL:tel:(240)315-9780 +ADR:;;6990 Kimberley Lane;Minooka;IL;60447; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Qui eum amet praesent qui minim nibh nisl aliquam luptatum eum. +ADR:;;3104 Cottage Glen Cove;Lepanto;AR;72354; +N:Halverson;Linnie;;; +IMPP:sip:linnie@sip.linphone.org +FN:Linnie Halverson +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19470102 +TEL:tel:(202)268-3906 +FN:Daphne Dow +ORG:Provider Studio Direct +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19930717 +EMAIL:e.choi@commodoeros.edu +FN:Earline Choi +ADR:;;8771 Lakeside Drive;Roy;MT;59471; +IMPP:sip:earline@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Mattie Bragg +IMPP:sip:mattie@sip.linphone.org +ADR:;;658 Merenerm Avenue;Topeka;KS;66629; +GENDER:F +BDAY:19580220 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Novotny;Galen;;; +TEL:tel:(802)326-1682 +IMPP:sip:galen@sip.linphone.org +ORG:Future Design +FN:Galen Novotny +ADR:;;3919 Sunny Slope Way;Sag Harbor;NY;11963; +BDAY:19400918 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Raymon Blair +EMAIL:raymon.blair@nibheu.gov +IMPP:sip:raymon@sip.linphone.org +TEL:tel:(775)879-1956 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(501)838-9703 +IMPP:sip:dorene@sip.linphone.org +BDAY:19600124 +EMAIL:d.strong@iustoodioad.edu +NOTE:Accumsan diam eu praesent. +FN:Dorene Strong +ADR:;;5810 Durley Parkway;Norwalk;CT;06860; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19371030 +NOTE:Et etaccumsan eu illum iusto invulputate luptatum ex vero facilisis. +ADR:;;7566 Silverbark Avenue;Johnston;SC;29832; +IMPP:sip:carlos@sip.linphone.org +FN:Carlos Worley +TEL:tel:(763)856-9354 +N:Worley;Carlos;;; +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Lura Hernandez +EMAIL:lura@nostrudnibh.net +ADR:;;5678 Woodhall Trail;Trenton;IL;62293; +IMPP:sip:lura@sip.linphone.org +GENDER:F +ORG:Max General Electronic +BDAY:19750618 +N:Hernandez;Lura;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Zzril molestie ad duis iustoodio dolore ea vero wisi. +BDAY:19631023 +ADR:;;9526 Riverain Lane;Wilder;ID;83676; +EMAIL:gena@doloresuscipit.info +ORG:Digital Provider +N:Trapp;Gena;;; +FN:Gena Trapp +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Nance;Ervin;;; +FN:Ervin Nance +IMPP:sip:ervin@sip.linphone.org +NOTE:Eros molestie nulla in exerci luptatumzzril autem dignissim blandit ea. +GENDER:O +BDAY:19740909 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:haywood@sip.linphone.org +NOTE:Et lobortis aliquam duis illum nibh exerci qui commodoconsequat luptatumzzril. +EMAIL:haywood.chew@nislutiustoodio.tv +GENDER:O +FN:Haywood Chew +ADR:;;7229 Melville Drive;El Paso;TX;88519; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Jed Wooten +BDAY:19670619 +N:Wooten;Jed;;; +NOTE:Iustoodio dignissim esse delenit. +ORG:Consulting West Data +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19400105 +TEL:tel:(631)679-9630 +ORG:Contract Federated Max +NOTE:Blandit tation etaccumsan minim duis facilisis. +GENDER:F +FN:Martha Flanigan +EMAIL:martha.flanigan@eratconsequat.us +N:Flanigan;Martha;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19450122 +NOTE:Consectetuer aliquip nonummy facilisi dignissim. +TEL:tel:(810)208-7665 +FN:Misti Nickerson +EMAIL:misti@nonummyqui.tv +ORG:Construction East Software +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19660809 +IMPP:sip:major@sip.linphone.org +NOTE:Molestie enim esse etaccumsan diam at luptatumzzril. +N:Carpenter;Major;;; +GENDER:O +FN:Major Carpenter +EMAIL:major.carpenter@enimesse.com +ADR:;;8978 Thicket Parkway;Caldwell;TX;77836; +ORG:Speed Network Internet +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +IMPP:sip:young@sip.linphone.org +NOTE:Lobortis wisi dolore ex duis ea. +ADR:;;5433 Southchester Street;Petersburg;AK;99833; +FN:Young Ng +ORG:Venture People +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(715)350-5828 +IMPP:sip:matthew@sip.linphone.org +ORG:Analysis South Consulting +FN:Matthew Stahl +GENDER:O +ADR:;;3911 Oakleigh Drive;Evansville;IN;47712; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Darwin Timmons +ADR:;;6584 Forest Hill Way;Washington;DC;20375; +GENDER:O +ORG:East East +N:Timmons;Darwin;;; +EMAIL:darwin.timmons@tedelenitaugue.eu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Velit iriuredolor blandit eros duis nislut adipiscing consequat delenit qui hendrerit accumsan eros elitsed. +TEL:tel:(904)842-8241 +ORG:Network Source +EMAIL:teri@elitsedodio.org +GENDER:N +ADR:;;9705 Tamerlane Way;Monroe;TN;38573; +FN:Teri York +IMPP:sip:teri@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Tovar;Laurie;;; +FN:Laurie Tovar +EMAIL:laurie@duisnostrud.info +NOTE:Vero nulla ex odio exerci te adipiscing praesent consequat. +BDAY:19880618 +ORG:Application Data Analysis +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:U +ORG:East Software Network +FN:Gaye Unger +IMPP:sip:gaye@sip.linphone.org +EMAIL:gaye.unger@minimquis.edu +NOTE:Ex laoreet duis enim at molestie suscipit sit ut molestie at nisl facilisi. +ADR:;;295 Chestnut Way;West Richland;WA;99353; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19571217 +ORG:Vision Systems Atlantic +FN:Nancy Hussey +EMAIL:nancy.hussey@facilisifacilisis.eu +GENDER:O +TEL:tel:(920)267-9308 +N:Hussey;Nancy;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19760320 +N:Dillard;Jimmie;;; +FN:Jimmie Dillard +IMPP:sip:jimmie@sip.linphone.org +TEL:tel:(740)311-3818 +ADR:;;8620 Eldridge Trail;Metairie;LA;70003; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Max Industries Interactive +N:Lujan;Una;;; +GENDER:F +IMPP:sip:una@sip.linphone.org +ADR:;;2095 Hunters Grove Avenue;Marshfield;WI;54472; +FN:Una Lujan +EMAIL:una@duisnulla.us +NOTE:Veniam iusto etaccumsan delenit dolore delenit aliquip ex dignissim et facilisis eum et et. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:una@sip.linphone.org +ADR:;;9870 Saint Marys Way;Portland;TN;37148; +ORG:Star Telecom +EMAIL:una.moen@lobortisfacilisis.edu +N:Moen;Una;;; +FN:Una Moen +GENDER:U +TEL:tel:(207)845-2254 +BDAY:19630110 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19710413 +TEL:tel:(843)189-8299 +FN:Elizabeth Dozier +IMPP:sip:elizabeth@sip.linphone.org +ADR:;;5421 Ingberg Circle;Scotland;AR;72141; +N:Dozier;Elizabeth;;; +NOTE:Vel suscipit praesent adipiscing consequat feugiat blandit delenit tationullamcorper dignissim. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Luciano Tellez +IMPP:sip:luciano@sip.linphone.org +ORG:West Vision Consulting +GENDER:O +NOTE:Wisi qui feugait consequat eros etaccumsan. +EMAIL:l.tellez@consequatdolore.info +ADR:;;1280 Laurie Street;Roseboom;NY;13450; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;209 Farmington Drive;Vidalia;GA;30474; +BDAY:19391221 +TEL:tel:(310)256-6583 +FN:Annamarie Jefferies +GENDER:O +IMPP:sip:annamarie@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:M +EMAIL:b.tirado@hendreritveniam.gov +FN:Barry Tirado +ORG:Medicine Telecom Solutions +ADR:;;3293 Olinda Cove;Ewing;VA;24248; +N:Tirado;Barry;;; +NOTE:Lorem autem diam nonummy duis. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Delenitaugue dignissim exerci consequatvel ut nulla ex. +ADR:;;4089 Duckhorn Parkway;Farmville;NC;27828; +FN:Elbert Hawes +IMPP:sip:elbert@sip.linphone.org +GENDER:U +BDAY:19531016 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:c.janes@loremzzril.org +N:Janes;Cary;;; +NOTE:Dolore autem invulputate suscipit. +BDAY:19791215 +ADR:;;4733 Holcombe Parkway;Saint Paul;MN;55111; +FN:Cary Janes +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(409)764-1483 +FN:Charley Sewell +ADR:;;7341 Cornwall Cove;Pelican Lake;WI;54463; +ORG:Universal Vision Construction +N:Sewell;Charley;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +NOTE:At consequat facilisi dignissim delenitaugue etaccumsan. +EMAIL:m.rauch@blanditex.net +FN:Monty Rauch +IMPP:sip:monty@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Treadwell;Chelsey;;; +FN:Chelsey Treadwell +NOTE:Duis autem nulla laoreet lobortis iriure feugait nulla tation suscipit. +BDAY:19900518 +EMAIL:chelsey.treadwell@aliquipfeugait.info +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Tillie Slattery +ORG:Data Bell Digital +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(563)356-5376 +FN:Robby Lombardo +BDAY:19410809 +GENDER:U +NOTE:Duis eros ea aliquip hendrerit nulla ipsum nostrud ea. +ORG:Advanced Analysis +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Source Frontier +GENDER:N +BDAY:19900731 +EMAIL:fern@inblandit.net +ADR:;;9620 Carters Grove Way;Montgomery;AL;36142; +FN:Fern Alicea +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Hope;Andreas;;; +FN:Andreas Hope +GENDER:O +ORG:Star Architecture +IMPP:sip:andreas@sip.linphone.org +TEL:tel:(260)790-2040 +EMAIL:a.hope@elitsednostrud.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Damian Hickman +N:Hickman;Damian;;; +IMPP:sip:damian@sip.linphone.org +ORG:East Digital Innovation +GENDER:O +TEL:tel:(801)339-8356 +NOTE:Minim volutpat suscipit dolore enim nulla diam duis. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Bell Medicine +FN:Russell Lenz +GENDER:U +TEL:tel:(412)505-9598 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19441129 +NOTE:Velit feugait minim vero accumsan. +ADR:;;7576 Old Village Circle;East Elmhurst;NY;11370; +EMAIL:zenaida.penn@essedelenit.us +FN:Zenaida Penn +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:kellie.alonzo@facilisiadipiscing.info +FN:Kellie Alonzo +IMPP:sip:kellie@sip.linphone.org +NOTE:Vel molestie suscipit etaccumsan nulla feugait suscipit in in. +ORG:Power Innovation +TEL:tel:(757)588-5598 +N:Alonzo;Kellie;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19910523 +GENDER:M +ORG:Research Technology North +FN:Gerardo Babb +TEL:tel:(321)199-3366 +EMAIL:g.babb@dolorete.gov +N:Babb;Gerardo;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Carrier;Denise;;; +FN:Denise Carrier +GENDER:F +EMAIL:denise@eumvelit.gov +IMPP:sip:denise@sip.linphone.org +NOTE:Vero nulla facilisi minim elitsed facilisis. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:rosalina.chambliss@ullamcorperconsequatvel.net +FN:Rosalina Chambliss +ADR:;;2747 Misty Creek Avenue;Clewiston;FL;33440; +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19670319 +TEL:tel:(202)148-8351 +ADR:;;9393 Willard Cove;Mcgrew;NE;69353; +FN:Rosemarie Morey +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19610728 +N:Simone;Mohamed;;; +NOTE:Invulputate eum nostrud qui veniamquis vulputate feugiat velit facilisi iusto enim zzril accumsan vel. +EMAIL:m.simone@quisconsectetuer.info +FN:Mohamed Simone +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Sills;Berry;;; +BDAY:19631225 +FN:Berry Sills +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Gavin Bain +GENDER:M +N:Bain;Gavin;;; +TEL:tel:(785)763-4544 +NOTE:Enim duis delenit ea lorem hendrerit illum dignissim nislut dolore. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Ulysses Daley +N:Daley;Ulysses;;; +EMAIL:ulysses@lobortisdelenitaugue.gov +ADR:;;8321 Knoll Cove;Houghton;SD;57449; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Data Consulting Studio +IMPP:sip:miguel@sip.linphone.org +EMAIL:miguel.aguiar@duisdignissim.edu +N:Aguiar;Miguel;;; +NOTE:Feugait hendrerit dolore ex iriure nulla dolore tation dolore autem illum. +FN:Miguel Aguiar +BDAY:19460609 +ADR:;;1563 Northwestern Cove;Boncarbo;CO;81024; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Benge;Joelle;;; +ORG:Technology Internet Federated +BDAY:19410104 +FN:Joelle Benge +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:leonard@sip.linphone.org +GENDER:M +FN:Leonard Chesser +ADR:;;5180 Bryn Mawr Drive;Carlsbad;CA;92018; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19791012 +GENDER:F +EMAIL:m.churchill@uthendrerit.com +NOTE:Vel ipsum facilisis zzril ut nostrud vel ut ex eum Utwisi ad facilisi. +ADR:;;1042 Gumleaf Circle;Oakford;IN;46965; +FN:Millicent Churchill +N:Churchill;Millicent;;; +IMPP:sip:millicent@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Doloremagna ad et lobortis etaccumsan etaccumsan blandit luptatumzzril. +FN:Caroline Norton +TEL:tel:(949)837-4906 +IMPP:sip:caroline@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Erwin Moore +GENDER:U +N:Moore;Erwin;;; +ORG:South Data Virtual +NOTE:Lorem feugait vero minim tationullamcorper eu velit luptatumzzril dolore euismod luptatumzzril feugait illum. +ADR:;;570 Kimbrough Grove Street;Des Moines;IA;50350; +BDAY:19850717 +TEL:tel:(928)760-6761 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Nettles;Jarred;;; +GENDER:O +FN:Jarred Nettles +TEL:tel:(283)163-6727 +IMPP:sip:jarred@sip.linphone.org +ORG:Solutions Power +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(509)199-3473 +ORG:Contract Galaxy +BDAY:19431202 +FN:Brigitte Kidd +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Sheffield;Hai;;; +IMPP:sip:hai@sip.linphone.org +ORG:Building Digital +BDAY:19731029 +NOTE:Dolor lobortis duis et. +FN:Hai Sheffield +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:rafaela@sip.linphone.org +FN:Rafaela Casteel +BDAY:19620118 +TEL:tel:(228)966-4053 +NOTE:Velit eu te minim et ad illum eu velit accumsan minim vulputate erat consequat. +N:Casteel;Rafaela;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Vision Virtual +FN:Laverne Bottoms +EMAIL:laverne@autemautem.net +N:Bottoms;Laverne;;; +GENDER:M +BDAY:19790628 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;5234 Centre Oak Parkway;Westernport;MD;21562; +FN:Consuelo Ezell +ORG:Pacific Analysis Solutions +EMAIL:consuelo@doloredolor.com +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(606)741-6168 +ADR:;;5426 Fairlawn Parkway;Genoa;OH;43430; +BDAY:19810228 +EMAIL:a.flanigan@exexerci.tv +GENDER:M +NOTE:Consequat delenitaugue consectetuer commodoconsequat in dolore. +IMPP:sip:amado@sip.linphone.org +FN:Amado Flanigan +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Mindy Hamm +EMAIL:mindy.hamm@delenitsit.gov +IMPP:sip:mindy@sip.linphone.org +BDAY:19960708 +ADR:;;6232 Last Arrow Way;Clear;AK;99704; +NOTE:Tationullamcorper consequatvel ut nulla. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:joey.lowry@exercidolore.com +TEL:tel:(281)603-8741 +N:Lowry;Joey;;; +ADR:;;9491 Port Charlotte Way;Panama City;FL;32403; +FN:Joey Lowry +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Gladys Horvath +BDAY:19600701 +GENDER:N +ORG:Source Max Industries +EMAIL:g.horvath@ettincidunt.info +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Alden Burns +N:Burns;Alden;;; +TEL:tel:(702)624-2531 +ADR:;;9605 Blackhaw Trail;Jacksonville;FL;32236; +EMAIL:alden.burns@suscipitvulputate.org +ORG:Star Max +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:d.mayhew@suscipithendrerit.info +GENDER:F +ADR:;;3147 Sibelius Street;Ewing;IL;62836; +ORG:Venture Digital Electronic +FN:Deborah Mayhew +BDAY:19401115 +IMPP:sip:deborah@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Humes;Susie;;; +EMAIL:s.humes@doloreinvulputate.eu +ADR:;;5019 Lakemere Trail;Cabot;VT;05647; +ORG:Solutions Studio Direct +FN:Susie Humes +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Speed Signal North +NOTE:Zzril vero ex nulla lobortis elitsed autem lobortis esse ea accumsan facilisis. +FN:Major Dean +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +ORG:People Consulting East +TEL:tel:(802)912-7813 +FN:Hilda Driggers +N:Driggers;Hilda;;; +EMAIL:h.driggers@iriuredolorenim.gov +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Magdalene Mata +IMPP:sip:magdalene@sip.linphone.org +GENDER:N +TEL:tel:(718)143-9852 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Franklyn Pilcher +ORG:Power Analysis Technology +IMPP:sip:franklyn@sip.linphone.org +N:Pilcher;Franklyn;;; +EMAIL:f.pilcher@nostrudqui.net +ADR:;;6511 Kimbrough Park Way;Bremen;IN;46506; +GENDER:M +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Vel molestie veniam iriuredolor consequatvel nonummy luptatumzzril enim ipsum facilisis amet euismod hendrerit eufeugiat. +EMAIL:s.casteel@molestieexerci.com +FN:Shirley Casteel +TEL:tel:(360)694-1968 +ORG:Frontier Telecom +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Consequatvel lorem nostrud facilisis amet minim tationullamcorper consectetuer autem lorem hendrerit. +FN:Lyle Langford +EMAIL:lyle@consequatamet.org +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19771202 +TEL:tel:(775)166-6772 +NOTE:Zzril accumsan Utwisi ad vulputate. +EMAIL:f.lunn@nonummyutwisi.tv +ADR:;;1808 Norwich Lane;Bay Saint Louis;MS;39520; +FN:Fawn Lunn +GENDER:O +N:Lunn;Fawn;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +ORG:Adventure Consulting +BDAY:19631108 +ADR:;;5153 Londonderry Drive;Windham;ME;04062; +EMAIL:shanta@consequatad.gov +NOTE:Feugiat odio te sit ea etaccumsan. +FN:Shanta Phifer +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;7730 Overhill Circle;Beaverton;OR;97007; +EMAIL:gerald.stanfield@dignissimullamcorper.edu +FN:Gerald Stanfield +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:tosha.rincon@atutwisi.tv +TEL:tel:(878)720-1453 +BDAY:19801015 +ORG:Architecture Alpha Frontier +FN:Tosha Rincon +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19831012 +TEL:tel:(208)582-6145 +IMPP:sip:mara@sip.linphone.org +FN:Mara Parish +ORG:Power Federated +GENDER:F +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(337)952-3263 +GENDER:F +N:Cameron;Enid;;; +IMPP:sip:enid@sip.linphone.org +FN:Enid Cameron +EMAIL:enid@essequis.info +ADR:;;1523 Gainesway Parkway;Schooleys Mountain;NJ;07870; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Dignissim veniamquis odio feugait iriure qui molestie esse consectetuer iusto vero luptatum ut dolore. +FN:Drew Keys +ORG:Medicine Provider Data +TEL:tel:(228)736-9321 +GENDER:N +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:U +TEL:tel:(715)156-1312 +N:Goad;Jack;;; +FN:Jack Goad +IMPP:sip:jack@sip.linphone.org +NOTE:Elitsed lobortis at erat tationullamcorper. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:U +EMAIL:juliana.bailey@veliriure.tv +N:Bailey;Juliana;;; +IMPP:sip:juliana@sip.linphone.org +FN:Juliana Bailey +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:jake.curtin@lobortisminim.org +IMPP:sip:jake@sip.linphone.org +ORG:Solutions Electronic +TEL:tel:(914)636-8182 +GENDER:N +ADR:;;9949 Stone Mill Parkway;Spanish Fort;AL;36527; +N:Curtin;Jake;;; +FN:Jake Curtin +BDAY:19920304 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Chung Somerville +EMAIL:chung@commodoet.eu +IMPP:sip:chung@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Coleen Seymour +ADR:;;9675 Norwich Circle;Dayton;OH;45432; +NOTE:Illum ex veniamquis vel ad in consectetuer. +TEL:tel:(541)730-1206 +IMPP:sip:coleen@sip.linphone.org +ORG:Alpha Frontier +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19890103 +IMPP:sip:rico@sip.linphone.org +N:Pagan;Rico;;; +FN:Rico Pagan +NOTE:Iusto amet suscipit suscipit eros facilisi euismod. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(562)414-9123 +GENDER:U +IMPP:sip:claire@sip.linphone.org +FN:Claire Gustafson +NOTE:Etaccumsan etaccumsan lobortis eu amet iusto. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Universal Federated +BDAY:19631102 +FN:Boyce Loyd +NOTE:Enim duis nostrud qui ad autem. +TEL:tel:(319)554-8033 +ADR:;;6053 Deerfield Street;Feeding Hills;MA;01030; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:n.ballinger@minimminim.org +GENDER:U +FN:Nellie Ballinger +ORG:Speed General +TEL:tel:(541)650-8193 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19960509 +N:Jean;Rosie;;; +FN:Rosie Jean +ORG:Architecture Medicine Star +EMAIL:rosie.jean@wisiad.edu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Madeline Terrill +NOTE:Consequat dolor nulla vel. +BDAY:19780219 +N:Terrill;Madeline;;; +EMAIL:madeline.terrill@exvel.tv +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Etaccumsan eum odio nulla iustoodio delenitaugue illum praesent. +FN:Marcellus Ziegler +TEL:tel:(540)916-3710 +BDAY:19920902 +ADR:;;1309 Itasca Cove;Huggins;MO;65484; +GENDER:O +ORG:Consulting Omega Consulting +N:Ziegler;Marcellus;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Jeffrey;Mamie;;; +FN:Mamie Jeffrey +NOTE:Hendrerit minim esse esse. +IMPP:sip:mamie@sip.linphone.org +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(227)441-3118 +ORG:Speed People Net +ADR:;;7357 Crooked Oak Avenue;Indio;CA;92203; +FN:Frances Keefe +BDAY:19380115 +IMPP:sip:frances@sip.linphone.org +GENDER:M +EMAIL:frances.keefe@atesse.net +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;7208 Donnington Drive;Sutherland Springs;TX;78161; +N:Wingate;Tom;;; +TEL:tel:(207)776-3150 +NOTE:Eros at blandit tationullamcorper consequatvel dolor nislut facilisis. +EMAIL:tom@nibhblandit.tv +GENDER:U +FN:Tom Wingate +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:U +N:Boynton;Earline;;; +EMAIL:e.boynton@utillum.tv +FN:Earline Boynton +NOTE:Invulputate qui dolore luptatumzzril vulputate commodo odio exerci te dolore lobortis lorem te. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(706)735-1344 +BDAY:19790618 +IMPP:sip:felicita@sip.linphone.org +FN:Felicita Covey +NOTE:Feugiat augue blandit nibh euismod adipiscing dolor wisi. +ORG:South Provider Technology +GENDER:N +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Avery;Gil;;; +FN:Gil Avery +NOTE:Te tation ex Utwisi. +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Jake Mitchel +GENDER:U +IMPP:sip:jake@sip.linphone.org +BDAY:19790922 +ADR:;;4382 Wolf River Avenue;Decatur;IL;62521; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:M +IMPP:sip:grady@sip.linphone.org +BDAY:19470916 +EMAIL:g.dockery@exerciiusto.net +TEL:tel:(785)192-3133 +FN:Grady Dockery +ORG:Hardware Electronics Research +ADR:;;4429 Kelvin Cove;Helena;AL;35080; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Maynard Conley +ORG:Bell Hill Venture +EMAIL:maynard.conley@uteum.us +TEL:tel:(702)924-6785 +N:Conley;Maynard;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19480529 +NOTE:Ad in nulla hendrerit iusto zzril facilisis. +GENDER:M +FN:Randall Pepper +IMPP:sip:randall@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;1896 Carlingford Drive;Manhattan;KS;66503; +N:Denman;Elvira;;; +NOTE:Utwisi qui nislut ex dolor nostrud dolore consequat praesent laoreet iriuredolor feugiat iusto. +BDAY:19500416 +GENDER:U +FN:Elvira Denman +ORG:Atlantic Studio +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:raymond@nonummyminim.eu +GENDER:O +NOTE:Autem nislut facilisi nibh eros ea sit in veniamquis et veniam. +FN:Raymond Metcalf +ORG:Max Design +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Lackey;Wyatt;;; +EMAIL:wyatt.lackey@veroiustoodio.tv +FN:Wyatt Lackey +ADR:;;7409 Misty Meadow Lane;Panama City;FL;32401; +IMPP:sip:wyatt@sip.linphone.org +BDAY:19491022 +TEL:tel:(540)990-9914 +NOTE:Ut odio dolore ex diam vulputate aliquam delenit dolore molestie. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Irwin Salisbury +BDAY:19550820 +N:Salisbury;Irwin;;; +GENDER:M +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:M +FN:Winford Pollard +EMAIL:winford.pollard@nislutex.gov +BDAY:19660114 +TEL:tel:(718)148-5105 +ORG:Building Resource Advanced +NOTE:Te lobortis ad enim feugait exerci zzril. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Sommers;Lavern;;; +ORG:Architecture Solutions Digital +GENDER:O +BDAY:19360727 +FN:Lavern Sommers +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:U +IMPP:sip:corinne@sip.linphone.org +BDAY:19780504 +TEL:tel:(918)338-6635 +ORG:Galaxy Source Hill +FN:Corinne Holloman +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(352)712-6838 +NOTE:Et autem wisi duis dolore dolor ex eu eufeugiat eufeugiat eros. +IMPP:sip:justina@sip.linphone.org +N:Jacobsen;Justina;;; +ADR:;;2139 Valley Crest Lane;Carthage;NY;13619; +FN:Justina Jacobsen +ORG:Research Studio Building +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Bell Analysis +IMPP:sip:joel@sip.linphone.org +N:Pedersen;Joel;;; +TEL:tel:(757)276-1874 +BDAY:19520815 +FN:Joel Pedersen +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Industries Contract Power +EMAIL:carlo@enimvel.edu +N:Blanco;Carlo;;; +TEL:tel:(708)322-7176 +FN:Carlo Blanco +GENDER:N +NOTE:Ut duis ad et doloremagna ea volutpat ut tation dolore praesent lobortis vero feugiat. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:gordon@utea.com +ADR:;;7519 Nordic Cove;Pierson;IA;51048; +FN:Gordon Major +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;57 Ilo Way;Riverdale;MI;48877; +EMAIL:c.appleton@doloredignissim.us +FN:Cyrus Appleton +TEL:tel:(626)148-5783 +NOTE:In erat vulputate minim. +ORG:Solutions Net +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Anne Worth +ORG:Frontier Research +EMAIL:anne@dignissimdolore.gov +TEL:tel:(605)854-8333 +NOTE:Veniamquis tincidunt et Utwisi ea praesent ex in vero eros in facilisi vero autem. +BDAY:19810423 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(949)636-7406 +NOTE:Nislut vero ut et nulla augue te nibh dolor facilisis. +IMPP:sip:rhoda@sip.linphone.org +ADR:;;7953 Village Shops Drive;Cincinnati;OH;45217; +FN:Rhoda Valle +EMAIL:rhoda@vellobortis.edu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Flynn;Joni;;; +FN:Joni Flynn +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Trudy Herr +GENDER:O +BDAY:19950410 +TEL:tel:(870)128-5632 +ORG:Source Innovation Pacific +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19520606 +ORG:Interactive Building West +FN:Elisha Orton +NOTE:Lorem vel exerci ad consequat dolor. +ADR:;;625 Echo Lane;Grandin;MO;63943; +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:kelley@sip.linphone.org +ADR:;;6916 Itasca Avenue;Leesburg;FL;34748; +EMAIL:kelley@dolorenostrud.net +FN:Kelley Westfall +ORG:Direct Medicine +TEL:tel:(802)758-1490 +GENDER:F +N:Westfall;Kelley;;; +BDAY:19460411 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19790128 +N:Bullock;Orval;;; +FN:Orval Bullock +NOTE:Luptatumzzril eros duis duis qui praesent etaccumsan suscipit wisi vero consequat volutpat. +ORG:Hardware Speed +TEL:tel:(219)215-8749 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +ADR:;;6768 Bow String Drive;Boons Camp;KY;41204; +FN:Beverley Newman +BDAY:19891027 +ORG:Hill Vision +EMAIL:beverley.newman@doloreinvulputate.edu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Sterling Fitzpatrick +GENDER:M +ORG:Design Signal Hill +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Vision Net Omega +EMAIL:nedra@eatationullamcorper.org +N:Fortier;Nedra;;; +TEL:tel:(772)483-8412 +FN:Nedra Fortier +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Hendrerit iustoodio tincidunt wisi elitsed vulputate nisl sit commodo nulla iustoodio. +FN:Vincent Mallard +ADR:;;9519 Rutherford Lane;Dickens;IA;51333; +IMPP:sip:vincent@sip.linphone.org +BDAY:19890414 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:clifford.spradlin@exin.edu +N:Spradlin;Clifford;;; +BDAY:19690222 +IMPP:sip:clifford@sip.linphone.org +FN:Clifford Spradlin +GENDER:O +TEL:tel:(202)792-5978 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Steward;Cari;;; +BDAY:19400827 +IMPP:sip:cari@sip.linphone.org +EMAIL:cari@dignissimmolestie.net +TEL:tel:(304)159-4819 +NOTE:Te dolor qui adipiscing qui minim minim ea ullamcorper vulputate esse minim qui facilisis. +FN:Cari Steward +ORG:Direct Frontier Provider +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Fletcher Mahan +EMAIL:fletcher@teiustoodio.tv +ORG:West Electronics South +NOTE:Lorem nulla eufeugiat ex tation duis tation facilisi hendrerit ex adipiscing eufeugiat enim. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;7257 Lydia Parkway;Tulsa;OK;74147; +BDAY:19930315 +ORG:Internet Internet +IMPP:sip:dane@sip.linphone.org +FN:Dane Kirkpatrick +NOTE:Nostrud vel qui doloremagna diam molestie dolore consequat commodo aliquip praesent. +N:Kirkpatrick;Dane;;; +TEL:tel:(907)178-2149 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;7967 Tamarack Avenue;West Point;IL;62380; +N:Casper;Dirk;;; +BDAY:19591205 +GENDER:U +FN:Dirk Casper +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Godinez;Mohamed;;; +ADR:;;2877 Mulberry Circle;Elyria;OH;44036; +FN:Mohamed Godinez +GENDER:M +BDAY:19690102 +NOTE:Ut minim ullamcorper amet nonummy eum illum qui in consequat wisi ullamcorper minim. +TEL:tel:(864)488-8772 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:cari.pettway@utfeugiat.net +TEL:tel:(513)693-9539 +ADR:;;4994 Thicket Trail;Spring Lake;MN;56680; +FN:Cari Pettway +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(339)126-8466 +IMPP:sip:graham@sip.linphone.org +NOTE:At molestie blandit dignissim dolore vero dolore vel. +BDAY:19910118 +ADR:;;445 Brewers Trail;Spring Valley;OH;45370; +FN:Graham Kinder +N:Kinder;Graham;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Telecom Max +TEL:tel:(952)417-9567 +ADR:;;9979 Waverly Avenue;Lake Charles;LA;70629; +FN:Rachelle Marlow +IMPP:sip:rachelle@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19580106 +FN:Angela Orr +ORG:Solutions Analysis Source +ADR:;;5139 Rico Way;Midwest;WY;82643; +GENDER:F +IMPP:sip:angela@sip.linphone.org +TEL:tel:(701)521-8618 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Rex Condon +EMAIL:r.condon@hendreritdolore.gov +NOTE:Iriure delenit eu autem ea dolore et et facilisis doloremagna nulla nibh ex ex. +IMPP:sip:rex@sip.linphone.org +GENDER:N +TEL:tel:(252)198-4158 +ORG:Federated Consulting People +N:Condon;Rex;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Technology Systems Vision +FN:Casandra Fry +GENDER:F +IMPP:sip:casandra@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(907)422-7367 +FN:Belva Jacoby +ADR:;;8582 Kersh Avenue;Hawley;TX;79525; +ORG:Star Graphics General +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(607)966-2450 +GENDER:M +EMAIL:c.soileau@suscipitfeugiat.tv +ORG:Data Resource Contract +FN:Connie Soileau +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:U +ORG:Solutions Hardware +FN:Josef Eastman +IMPP:sip:josef@sip.linphone.org +EMAIL:josef@etvelit.us +NOTE:Veniam quis nostrud at adipiscing hendrerit vel praesent odio exerci diam vulputate. +N:Eastman;Josef;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Hugh Zeller +EMAIL:hugh@essenislut.com +TEL:tel:(978)154-4609 +NOTE:Qui veniamquis aliquip enim. +GENDER:M +N:Zeller;Hugh;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Franklyn Fanning +TEL:tel:(952)756-2132 +ORG:Galaxy Interactive Frontier +N:Fanning;Franklyn;;; +EMAIL:franklyn.fanning@molestieexerci.tv +NOTE:Volutpat wisi lobortis volutpat quis in nulla exerci. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Bettina Polk +ADR:;;4699 Mayfield Circle;Westphalia;MI;48894; +NOTE:Vel molestie volutpat consequat dolore hendrerit tation eum dolor amet euismod facilisis. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Juliana Mabe +GENDER:N +EMAIL:juliana.mabe@feugiatet.com +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Natalie Harbin +ADR:;;4372 Myrtlea Parkway;Elgin;IL;60123; +TEL:tel:(314)582-2722 +EMAIL:natalie.harbin@tinciduntdolore.net +NOTE:Nonummy ullamcorper praesent feugait facilisi. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Network Source Bell +FN:Lana Kent +ADR:;;1714 Neal Lane;Applegate;CA;95703; +NOTE:Eufeugiat consectetuer iusto exerci erat. +N:Kent;Lana;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Kitchen;Carolyn;;; +FN:Carolyn Kitchen +NOTE:In in consequat exerci aliquam consequatvel duis facilisi molestie molestie. +ORG:Venture West Universal +BDAY:19420311 +EMAIL:carolyn.kitchen@erosluptatumzzril.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Johnathan Berrios +N:Berrios;Johnathan;;; +ORG:Pacific Research Contract +NOTE:Utwisi lobortis dolore etaccumsan velit. +IMPP:sip:johnathan@sip.linphone.org +BDAY:19590807 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Ceja;Willard;;; +FN:Willard Ceja +EMAIL:w.ceja@molestiefeugait.tv +BDAY:19710225 +ORG:Data Atlantic +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19820109 +NOTE:Hendrerit feugait illum duis. +FN:Nadia Gamez +N:Gamez;Nadia;;; +TEL:tel:(609)572-1467 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Pam Frank +BDAY:19940322 +ADR:;;8944 Trailwood Cove;New Hyde Park;NY;11044; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:ambrose@quinislut.net +TEL:tel:(252)984-1145 +ADR:;;9229 Settlers Street;Kaw City;OK;74641; +FN:Ambrose Osborne +ORG:Omega Vision Speed +IMPP:sip:ambrose@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Alpha Digital Adventure +EMAIL:elinor.wahl@etduis.us +N:Wahl;Elinor;;; +BDAY:19951209 +FN:Elinor Wahl +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Weatherly;Reynaldo;;; +BDAY:19730820 +GENDER:M +ADR:;;9878 Leesburg Avenue;Anchorage;AK;99516; +FN:Reynaldo Weatherly +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +NOTE:Et adipiscing elitsed vero duis nulla aliquip nulla vel. +FN:Athena Fullerton +IMPP:sip:athena@sip.linphone.org +BDAY:19730831 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:lorena@utnonummy.info +GENDER:U +FN:Lorena Bruns +ADR:;;5586 Oakgreen Avenue Avenue;Newalla;OK;74857; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:hallie@sip.linphone.org +ORG:Research Speed +ADR:;;1671 Stamford Street;Sycamore Valley;OH;43789; +GENDER:O +FN:Hallie Howland +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:dayna.boehm@feugiataliquam.edu +IMPP:sip:dayna@sip.linphone.org +ADR:;;3210 Honeye Drive;Hudson;OH;44237; +GENDER:U +BDAY:19380312 +FN:Dayna Boehm +N:Boehm;Dayna;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Irvin Aldrich +BDAY:19710329 +NOTE:Sit delenit ea duis accumsan qui iusto consequatvel consequat. +TEL:tel:(727)365-1476 +GENDER:U +ADR:;;1985 Ravenhill Street;Land O Lakes;WI;54540; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Universal Max Interactive +IMPP:sip:clemente@sip.linphone.org +EMAIL:clemente@tevolutpat.edu +BDAY:19960313 +FN:Clemente Billings +N:Billings;Clemente;;; +ADR:;;5853 Barkers Landing Lane;Yelm;WA;98597; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Feugait dolor elitsed consequat vulputate commodoconsequat doloremagna dolore duis. +N:Byrne;Elliot;;; +GENDER:M +FN:Elliot Byrne +TEL:tel:(636)273-9153 +EMAIL:elliot@exerciluptatumzzril.eu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:rey@sip.linphone.org +GENDER:O +FN:Rey Joiner +N:Joiner;Rey;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Tationullamcorper vel Utwisi commodoconsequat suscipit nostrud ea Utwisi feugait in enim molestie. +FN:Luis Marx +ORG:Building Net Hill +N:Marx;Luis;;; +ADR:;;2743 Paddock Parkway;Portsmouth;NH;03804; +TEL:tel:(212)293-2197 +EMAIL:luis@nullatincidunt.edu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:cornell@sip.linphone.org +FN:Cornell Jaynes +GENDER:M +BDAY:19760422 +EMAIL:cornell@tinciduntaliquam.edu +TEL:tel:(256)596-7561 +N:Jaynes;Cornell;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:alma@sip.linphone.org +FN:Alma Archer +NOTE:Amet wisi ea tationullamcorper eu dolore quis ad nulla. +GENDER:F +EMAIL:alma.archer@eate.us +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Connor;Mellisa;;; +NOTE:Veniam consectetuer luptatum duis velit ea luptatumzzril facilisi aliquam at. +ORG:Virtual Source Pacific +TEL:tel:(219)685-9239 +IMPP:sip:mellisa@sip.linphone.org +FN:Mellisa Connor +ADR:;;3256 Watkins Circle;Cucumber;WV;24826; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19421005 +FN:Yolanda Brumfield +ORG:Pacific Advanced +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +FN:Amy Otoole +TEL:tel:(903)944-2371 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Jessie Freed +ORG:Electronics Alpha Innovation +TEL:tel:(859)166-9395 +EMAIL:jessie@dolorein.net +N:Freed;Jessie;;; +NOTE:At etaccumsan etaccumsan praesent adipiscing aliquam duis tationullamcorper quis iustoodio at odio dolor nibh. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:caroline@adquis.info +ORG:Graphics Software +BDAY:19510506 +FN:Caroline Pardo +N:Pardo;Caroline;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Merle Marlowe +EMAIL:merle@commodoconsequatesse.com +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Net Universal +N:Cardona;Allen;;; +FN:Allen Cardona +ADR:;;1623 Amundson Circle;Republican Grove;VA;24585; +TEL:tel:(212)220-6995 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Sammons;Kelly;;; +NOTE:Velit dignissim zzril nostrud eum dolor duis velit illum. +FN:Kelly Sammons +ADR:;;6116 Washington Trail;Darrington;WA;98241; +ORG:Omega North Solutions +IMPP:sip:kelly@sip.linphone.org +GENDER:O +EMAIL:kelly.sammons@erosdolore.net +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;2785 Hunters Creek Way;Carthage;NC;28327; +BDAY:19750717 +IMPP:sip:louann@sip.linphone.org +GENDER:U +FN:Louann Hassell +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;5602 Merenerm Lane;Epps;LA;71237; +IMPP:sip:alphonse@sip.linphone.org +FN:Alphonse Naquin +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +FN:Georgette Peoples +TEL:tel:(252)277-1841 +N:Peoples;Georgette;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Breedlove;Hortencia;;; +TEL:tel:(270)978-4760 +FN:Hortencia Breedlove +IMPP:sip:hortencia@sip.linphone.org +ORG:Vision Power Consulting +EMAIL:hortencia.breedlove@dolorin.org +ADR:;;247 Deerfield Street;Otis;CO;80743; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Advanced Industries +ADR:;;8399 Savannah Cove;Owensville;MO;65066; +FN:Bertram Woodbury +N:Woodbury;Bertram;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(703)914-5006 +IMPP:sip:hilary@sip.linphone.org +ORG:Application Speed +N:Lowry;Hilary;;; +ADR:;;6341 Shepherdwood Way;Sharpsburg;NC;27878; +FN:Hilary Lowry +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Alisa Cosby +N:Cosby;Alisa;;; +ADR:;;7700 Westminster Lane;Annapolis;MD;21403; +NOTE:In luptatum et qui ex in eum aliquip in consequat. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19390425 +ORG:Federated East +ADR:;;7864 Huntcliff Avenue;Garrett;IN;46738; +TEL:tel:(267)701-1423 +FN:Haywood Greco +N:Greco;Haywood;;; +EMAIL:haywood.greco@volutpatamet.edu +IMPP:sip:haywood@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:goldie@sip.linphone.org +N:Brunner;Goldie;;; +BDAY:19440411 +TEL:tel:(925)601-3999 +ADR:;;3741 Fawnlake Parkway;Holmesville;OH;44633; +FN:Goldie Brunner +ORG:Signal Venture Internet +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Clouse;Sydney;;; +ADR:;;2915 Grove Mill Avenue;Saint Louis;MO;63146; +TEL:tel:(814)469-3252 +FN:Sydney Clouse +BDAY:19870314 +EMAIL:sydney.clouse@quislorem.gov +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Federated Virtual +BDAY:19690329 +FN:Vern Gault +ADR:;;354 Oakgreen Avenue Lane;Roland;IA;50236; +TEL:tel:(334)245-7649 +NOTE:Ut iriuredolor eum velit sit feugait facilisis molestie consequat sit suscipit consequat exerci qui. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Tanisha Gerard +TEL:tel:(956)245-3241 +ADR:;;661 Peacan Street;Albany;NY;12255; +ORG:Innovation Network Atlantic +IMPP:sip:tanisha@sip.linphone.org +N:Gerard;Tanisha;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Corine Barnhill +N:Barnhill;Corine;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Sosa;Phillis;;; +ORG:Speed Electronics Interactive +BDAY:19830211 +FN:Phillis Sosa +GENDER:F +NOTE:Feugiat dolor consequat autem invulputate vero. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(408)413-1117 +N:Daily;Theresa;;; +ADR:;;8043 Winding Oak Parkway;Owensboro;KY;42302; +FN:Theresa Daily +ORG:Vision Software West +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Facilisis nulla in qui nibh delenitaugue. +ADR:;;9 Turkey Avenue;Eastman;GA;31023; +N:Whyte;Adela;;; +FN:Adela Whyte +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Alene Culbertson +TEL:tel:(615)136-5531 +ADR:;;348 Cranberry Hill Parkway;Orleans;IN;47452; +BDAY:19820812 +NOTE:Duis consequat eros illum dolore consequatvel. +ORG:Hardware Virtual Galaxy +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Laoreet vulputate veniamquis suscipit nisl. +ORG:Federated Telecom Medicine +FN:Minerva Antonio +IMPP:sip:minerva@sip.linphone.org +BDAY:19550530 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Chrystal Ceja +TEL:tel:(315)774-5441 +EMAIL:c.ceja@velet.eu +ORG:Future Internet +IMPP:sip:chrystal@sip.linphone.org +N:Ceja;Chrystal;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Santo Green +N:Green;Santo;;; +IMPP:sip:santo@sip.linphone.org +EMAIL:s.green@velea.net +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Lenard Tribble +IMPP:sip:lenard@sip.linphone.org +ADR:;;3726 Crooked Oak Lane;Dellslow;WV;26531; +EMAIL:lenard.tribble@veroesse.eu +N:Tribble;Lenard;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19870724 +ADR:;;3546 Redhaw Drive;Brant;NY;14027; +EMAIL:darius.thibodeaux@euismoddolore.us +FN:Darius Thibodeaux +TEL:tel:(865)973-4720 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Qui nulla eros dolore ex. +BDAY:19500220 +IMPP:sip:nelda@sip.linphone.org +TEL:tel:(978)183-7665 +FN:Nelda Bumgarner +EMAIL:nelda@molestieat.net +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Chitwood;Gene;;; +FN:Gene Chitwood +ORG:Source Adventure +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(202)871-9815 +FN:Verna Justus +IMPP:sip:verna@sip.linphone.org +ADR:;;6083 Kimforest Lane;Milwaukee;WI;53202; +EMAIL:v.justus@eufeugiatmolestie.us +ORG:Galaxy Direct Solutions +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Myron Clarkson +EMAIL:myron@etiriuredolor.gov +ADR:;;9702 Pepper Avenue;Greeley;IA;52050; +IMPP:sip:myron@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Hill Virtual Innovation +TEL:tel:(878)123-3609 +ADR:;;4438 Haseley Avenue;Liberty;MO;64087; +IMPP:sip:sophie@sip.linphone.org +FN:Sophie Hutchens +NOTE:Facilisis ad dolore augue vulputate enim tation et adipiscing eros delenitaugue veniamquis commodoconsequat. +N:Hutchens;Sophie;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(724)605-5859 +N:Thibodeau;Jenna;;; +EMAIL:jenna@erosinvulputate.gov +FN:Jenna Thibodeau +IMPP:sip:jenna@sip.linphone.org +ORG:Medicine Analysis Research +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Lily Kay +ADR:;;3249 Manning Trail Cove;Nora Springs;IA;50458; +N:Kay;Lily;;; +TEL:tel:(607)839-8085 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:alene.chambers@adnonummy.info +IMPP:sip:alene@sip.linphone.org +ADR:;;881 Eastern Trail;Easley;SC;29640; +FN:Alene Chambers +ORG:Internet Innovation Analysis +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +FN:Bernice Spurgeon +ORG:Max Industries Interactive +EMAIL:bernice@eumodio.us +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;6042 Country Lane;Savannah;GA;31415; +ORG:Building Network +FN:Rochelle Perdue +EMAIL:rochelle.perdue@atipsum.edu +NOTE:Illum duis dolore aliquip delenitaugue illum. +GENDER:F +BDAY:19870203 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +FN:Abdul Earnest +EMAIL:abdul.earnest@aliquipduis.com +ORG:Virtual Net Network +N:Earnest;Abdul;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Zzril facilisi praesent molestie duis dolore minim hendrerit ut Utwisi hendrerit. +TEL:tel:(256)156-8043 +GENDER:M +FN:Bertram Shea +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:gertie@sip.linphone.org +FN:Gertie Okeefe +GENDER:F +EMAIL:g.okeefe@illumconsequat.net +BDAY:19451030 +ORG:Solutions Provider Consulting +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Joesph Crouch +ADR:;;840 Mistywood Street;Silverton;OR;97381; +BDAY:19700423 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Willy Culbertson +BDAY:19510105 +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +ADR:;;9241 Lakespur Cove;Toledo;IA;52342; +TEL:tel:(712)478-3301 +FN:Virginia Cain +BDAY:19400901 +N:Cain;Virginia;;; +IMPP:sip:virginia@sip.linphone.org +ORG:South Net +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Escobedo;Gretchen;;; +GENDER:F +FN:Gretchen Escobedo +BDAY:19631109 +IMPP:sip:gretchen@sip.linphone.org +NOTE:Suscipit ipsum elitsed consequat facilisi luptatumzzril ad etaccumsan at dignissim hendrerit iusto aliquip. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(914)639-8527 +IMPP:sip:derick@sip.linphone.org +FN:Derick Peeler +NOTE:Duis duis feugait autem nulla invulputate elitsed nibh enim ad blandit hendrerit. +ADR:;;2326 Omar Drive;Seaside Heights;NJ;08751; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Ophelia Harless +EMAIL:ophelia@minimmolestie.info +BDAY:19851007 +GENDER:U +ADR:;;3632 Rice Circle;Oak Park;IL;60302; +ORG:Max Frontier +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(360)967-2890 +EMAIL:j.bethea@infeugait.eu +ADR:;;3931 Kallie Lane;New York;NY;10025; +FN:Julianna Bethea +IMPP:sip:julianna@sip.linphone.org +BDAY:19500303 +ORG:Alpha Star Venture +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +NOTE:Hendrerit dignissim delenit adipiscing duis iriuredolor elitsed amet zzril augue dignissim. +IMPP:sip:andres@sip.linphone.org +FN:Andres Willis +ORG:Research Building Contract +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:armando@sip.linphone.org +EMAIL:armando@praesentenim.tv +NOTE:Eu nulla autem velit qui tincidunt volutpat invulputate feugait te. +N:Troutman;Armando;;; +TEL:tel:(352)806-8019 +FN:Armando Troutman +ORG:Speed Advanced Source +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;5949 Rancho Bauer Street;Dowling;MI;49050; +FN:Kendra Mccrory +IMPP:sip:kendra@sip.linphone.org +ORG:Solutions Industries North +GENDER:F +N:Mccrory;Kendra;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;3166 Germanwood Avenue;Grand Portage;MN;55605; +EMAIL:valorie.rudolph@illumenim.edu +ORG:Hardware Signal +FN:Valorie Rudolph +NOTE:Qui lobortis quis consequat vulputate velit. +IMPP:sip:valorie@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Hilario Coffman +NOTE:Hendrerit veniamquis duis feugiat vero erat tincidunt suscipit illum eu. +TEL:tel:(215)744-1584 +ORG:Star North Electronics +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Margo Zink +NOTE:Vel eros augue aliquip facilisi Utwisi iriuredolor. +IMPP:sip:margo@sip.linphone.org +TEL:tel:(718)662-1946 +N:Zink;Margo;;; +ORG:Solutions General Systems +EMAIL:margo@iriuredolornonummy.eu +BDAY:19970928 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:marco@sip.linphone.org +FN:Marco Towle +NOTE:Feugait autem exerci te. +ADR:;;4273 Leaning Ash Cove;Auburn;MI;48611; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Huey;Tiffany;;; +NOTE:Ut velit lobortis qui. +FN:Tiffany Huey +ORG:People Graphics +TEL:tel:(445)266-6359 +GENDER:N +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Sandy Bethea +NOTE:Tincidunt et velit enim suscipit et et dolore nonummy volutpat molestie consequat doloremagna. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Lobortis diam blandit eum eros qui tationullamcorper nostrud molestie commodo ad. +FN:Theresa Batiste +TEL:tel:(304)827-7923 +EMAIL:theresa.batiste@autemin.info +IMPP:sip:theresa@sip.linphone.org +ORG:Vision South Direct +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:daphne@sip.linphone.org +ORG:Star Analysis +ADR:;;8904 Dogwood Street;Runnemede;NJ;08078; +TEL:tel:(614)130-1297 +FN:Daphne Finn +BDAY:19781222 +N:Finn;Daphne;;; +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Willis Wofford +IMPP:sip:willis@sip.linphone.org +EMAIL:willis@feugiataliquip.net +NOTE:Et lobortis nulla autem aliquam dolor. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Vision Data Star +EMAIL:o.zepeda@iriuredolornulla.net +NOTE:Veniam ut etaccumsan vel. +IMPP:sip:olen@sip.linphone.org +BDAY:19620814 +FN:Olen Zepeda +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:delmar@sip.linphone.org +EMAIL:delmar@euismodconsequat.net +FN:Delmar Lashley +NOTE:Velit nostrud autem dolor facilisi dolore velit erat dolor praesent eu volutpat esse. +ORG:Bell Architecture +BDAY:19480522 +ADR:;;8803 Omaha Way;Sherburn;MN;56171; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Adventure People Architecture +TEL:tel:(563)757-5182 +GENDER:U +NOTE:Invulputate at autem praesent autem feugait. +IMPP:sip:vanessa@sip.linphone.org +N:Redding;Vanessa;;; +FN:Vanessa Redding +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:M +FN:Edward Pendleton +ADR:;;9365 Marylane Drive;Washington;DC;20437; +N:Pendleton;Edward;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +ADR:;;899 Rich Hill Drive;District Heights;MD;20753; +TEL:tel:(347)455-4907 +ORG:Network Direct Solutions +FN:Latoya Cardenas +BDAY:19890730 +N:Cardenas;Latoya;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:emma@adeum.edu +FN:Emma Keating +TEL:tel:(740)447-3113 +N:Keating;Emma;;; +IMPP:sip:emma@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;1592 Holly Spring Way;Wilson;OK;73463; +FN:Reggie Melton +ORG:Hill Electronics +BDAY:19360830 +EMAIL:reggie@blanditvero.com +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:cori@sip.linphone.org +ORG:Consulting Max +N:Sallee;Cori;;; +GENDER:U +EMAIL:cori@ateuismod.info +FN:Cori Sallee +BDAY:19450531 +NOTE:Lobortis ipsum duis amet facilisis. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19700625 +EMAIL:bobby@veltincidunt.net +NOTE:Ea autem consectetuer laoreet facilisi iriuredolor exerci veniam lorem feugait minim hendrerit. +N:Wendt;Bobby;;; +FN:Bobby Wendt +ADR:;;2710 Surrey Circle;Saint Anthony;IA;50239; +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:merrill@sip.linphone.org +FN:Merrill Queen +ORG:Federated Interactive +TEL:tel:(252)166-3312 +GENDER:M +ADR:;;3206 Elmhurst Circle;Turner;MT;59542; +N:Queen;Merrill;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Graphics Direct Electronics +FN:Mia Lipscomb +N:Lipscomb;Mia;;; +ADR:;;6538 Grove Avenue;Poplarville;MS;39470; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:nelda.cowell@doloreiriuredolor.com +N:Cowell;Nelda;;; +FN:Nelda Cowell +GENDER:U +ORG:Electronics Application Future +ADR:;;1982 Main Avenue;Church Rock;NM;87311; +TEL:tel:(717)147-1510 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Internet East Innovation +TEL:tel:(775)882-5617 +IMPP:sip:neal@sip.linphone.org +FN:Neal Dejesus +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:boyd@exillum.eu +TEL:tel:(701)597-8186 +N:Demarco;Boyd;;; +ORG:Omega Federated Hardware +FN:Boyd Demarco +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;5041 Shelton Circle;Tariffville;CT;06081; +FN:Rosario Schroeder +NOTE:Suscipit qui aliquam luptatumzzril esse veniamquis eufeugiat delenitaugue praesent te blandit doloremagna. +IMPP:sip:rosario@sip.linphone.org +EMAIL:rosario.schroeder@iustoodioad.org +GENDER:U +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19810909 +N:Edgar;Aletha;;; +ADR:;;8195 Fawnlake Way;Pottersville;NY;12860; +FN:Aletha Edgar +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19440606 +FN:Eugene Madrigal +GENDER:M +TEL:tel:(225)203-3413 +N:Madrigal;Eugene;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +FN:Rochelle Lamar +IMPP:sip:rochelle@sip.linphone.org +N:Lamar;Rochelle;;; +ADR:;;718 Plantation Street;Cleveland;OH;44130; +BDAY:19521202 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Illum dolore accumsan diam. +FN:Pauline Rico +BDAY:19570215 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(406)706-8518 +ADR:;;2003 Dewhurst Street;Dakota;IL;61018; +ORG:Electronic Contract South +FN:Ila Troy +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Shonda Durkin +N:Durkin;Shonda;;; +ADR:;;6547 Saddle Cove;Posey;CA;93260; +NOTE:Esse in luptatum hendrerit te vel elitsed dignissim molestie hendrerit. +ORG:Power Application Adventure +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Digital Graphics Power +FN:Adolph Prescott +IMPP:sip:adolph@sip.linphone.org +BDAY:19720906 +N:Prescott;Adolph;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Marquis;Hollis;;; +BDAY:19410702 +ADR:;;6748 Stone Mill Avenue;Gore;VA;22637; +ORG:Consulting West +GENDER:M +FN:Hollis Marquis +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;1363 Wheatley Parkway;Minden;TX;75680; +N:Yarborough;Helene;;; +FN:Helene Yarborough +BDAY:19451006 +ORG:South Medicine +TEL:tel:(864)176-7607 +GENDER:F +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:jacquelyn@sip.linphone.org +EMAIL:jacquelyn.wesley@etutwisi.org +ADR:;;2940 Riggs Trail;Shelby;IA;51570; +BDAY:19880217 +FN:Jacquelyn Wesley +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Commodo delenit ad feugiat diam commodoconsequat tationullamcorper lobortis. +TEL:tel:(910)662-1200 +FN:Elvira Haddad +N:Haddad;Elvira;;; +ADR:;;7656 Akerswood Drive;Honolulu;HI;96835; +BDAY:19770218 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:liliana@sip.linphone.org +GENDER:N +BDAY:19900912 +EMAIL:l.obrien@delenitea.com +NOTE:Velit amet praesent zzril. +TEL:tel:(616)678-8924 +FN:Liliana Obrien +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Velit vel molestie diam feugait eum amet blandit ipsum delenitaugue iriure praesent nulla in. +ORG:Software Galaxy +BDAY:19860528 +FN:Chong Goff +N:Goff;Chong;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Systems Signal Application +ADR:;;2358 Waxlander Lane;Omaha;NE;68131; +FN:Arlene Person +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(574)365-3098 +GENDER:O +N:Schumacher;Margarito;;; +EMAIL:margarito.schumacher@doloredoloremagna.us +FN:Margarito Schumacher +ADR:;;6743 Splinter Oak Circle;Louisville;KY;40205; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Source Omega +FN:Gregory Hancock +GENDER:M +EMAIL:gregory@dignissimnostrud.eu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:bernie@sip.linphone.org +NOTE:Consequatvel sit iustoodio lorem ex praesent aliquip nulla illum erat at. +ORG:Source Systems Solutions +GENDER:O +FN:Bernie Hoy +EMAIL:bernie@euillum.gov +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19601227 +TEL:tel:(425)800-2550 +IMPP:sip:rosalee@sip.linphone.org +ORG:General Power +EMAIL:r.billingsley@hendreritlobortis.com +FN:Rosalee Billingsley +N:Billingsley;Rosalee;;; +ADR:;;257 Olinda Circle;Butler;MD;21023; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:U +BDAY:19360408 +N:Lundberg;Annie;;; +EMAIL:annie.lundberg@inblandit.us +FN:Annie Lundberg +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:U +ADR:;;4625 Brenley Street;Scottsburg;OR;97473; +TEL:tel:(251)666-7534 +BDAY:19370521 +FN:Leigh Rupert +IMPP:sip:leigh@sip.linphone.org +N:Rupert;Leigh;;; +NOTE:Nisl at wisi eufeugiat nulla aliquip duis ullamcorper. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19880408 +N:Amos;Perla;;; +GENDER:F +FN:Perla Amos +EMAIL:perla@sitillum.edu +ORG:Power Provider +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Webster;Ron;;; +FN:Ron Webster +GENDER:M +NOTE:Lorem Utwisi ex zzril ad wisi exerci consequat qui Utwisi doloremagna eros. +BDAY:19800131 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Sammie Kolb +N:Kolb;Sammie;;; +ADR:;;2825 Garden Arbor Trail;Northport;AL;35476; +ORG:Systems Net Graphics +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Dora Cohn +BDAY:19690403 +ADR:;;8155 Southchester Way;Palmyra;IN;47164; +ORG:Atlantic Vision Solutions +EMAIL:dora@doloreluptatumzzril.tv +GENDER:N +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Elitsed illum autem lobortis autem. +EMAIL:r.boss@addolore.gov +ADR:;;9507 Monarda Circle;Sacramento;CA;94253; +GENDER:F +ORG:Vision Future +FN:Roseann Boss +BDAY:19721127 +N:Boss;Roseann;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(959)867-9387 +N:Ferrari;Terrence;;; +BDAY:19950404 +GENDER:U +FN:Terrence Ferrari +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +FN:Josue Cintron +N:Cintron;Josue;;; +NOTE:Suscipit et eros nostrud dolor esse veniamquis autem dignissim facilisis vel suscipit. +EMAIL:josue@duisat.tv +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Benny Eden +ADR:;;1541 Muir Cove;Peoria;AZ;85380; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;9986 Oxen Lane;Guadalupita;NM;87722; +TEL:tel:(502)431-6666 +FN:Caroline Burley +IMPP:sip:caroline@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +N:Carver;Shameka;;; +FN:Shameka Carver +BDAY:19790913 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +TEL:tel:(202)687-8815 +FN:Selma Dugger +NOTE:Blandit dolore enim hendrerit facilisi illum Utwisi duis vero ut dignissim blandit lobortis dolore. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:larissa@nostrudillum.net +ADR:;;8207 Nottingham Oaks Trail;Daniels;WV;25832; +FN:Larissa Parks +N:Parks;Larissa;;; +ORG:Direct North +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(501)607-4654 +EMAIL:twyla@essefacilisis.net +NOTE:Nislut esse accumsan lorem doloremagna nisl vero laoreet dignissim volutpat eros iusto qui exerci. +GENDER:F +ORG:Industries Provider Star +N:Brogan;Twyla;;; +FN:Twyla Brogan +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19640322 +NOTE:Ut aliquip eum qui duis ut feugait accumsan illum dolor. +IMPP:sip:valorie@sip.linphone.org +FN:Valorie Mcknight +GENDER:F +ORG:Hill Source Virtual +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Gayle Alfred +GENDER:N +N:Alfred;Gayle;;; +ORG:Software Virtual +IMPP:sip:gayle@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:U +BDAY:19600420 +N:Edwards;Carrol;;; +EMAIL:carrol.edwards@veniamquisnulla.edu +FN:Carrol Edwards +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Pacific Digital Graphics +EMAIL:tanner.mccabe@essedolore.us +TEL:tel:(714)728-5416 +FN:Tanner Mccabe +IMPP:sip:tanner@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Net Net +TEL:tel:(937)370-6620 +FN:Sylvia Nixon +N:Nixon;Sylvia;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Raymon Betz +NOTE:Iustoodio molestie nulla velit consectetuer. +TEL:tel:(218)860-6854 +EMAIL:r.betz@exercimolestie.info +ORG:Net Star Research +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Melba Pipkin +IMPP:sip:melba@sip.linphone.org +ADR:;;3539 Stamford Drive;North Charleston;SC;29415; +N:Pipkin;Melba;;; +NOTE:Velit duis dignissim vero. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Moshe Bowling +BDAY:19761212 +ORG:Medicine Innovation Vision +IMPP:sip:moshe@sip.linphone.org +N:Bowling;Moshe;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;378 Butterfly Parkway;Pearce;AZ;85625; +N:Faber;Martina;;; +ORG:Future Bell Universal +BDAY:19550719 +GENDER:N +FN:Martina Faber +NOTE:Ut consequat consectetuer et esse commodoconsequat iriure dolore quis. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(210)342-2848 +NOTE:Molestie esse minim feugiat aliquip ad facilisis velit invulputate autem consequat vel duis. +FN:Nan Fonseca +ADR:;;3252 Country Place Parkway;Greenfield;MO;65661; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Adan Olvera +NOTE:At doloremagna tationullamcorper duis. +TEL:tel:(774)295-5619 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Passmore;Sabina;;; +ADR:;;4620 Heathstone Drive;Mc Kinnon;WY;82938; +TEL:tel:(401)771-3988 +ORG:Building Medicine Industries +EMAIL:sabina.passmore@euut.us +GENDER:O +FN:Sabina Passmore +IMPP:sip:sabina@sip.linphone.org +BDAY:19510430 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Maryellen Cave +ORG:Star Source Star +EMAIL:maryellen@dolorefeugait.gov +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +ORG:Application Universal Building +FN:Luis Mcknight +NOTE:Praesent suscipit suscipit ad vero autem aliquip velit tincidunt. +TEL:tel:(641)712-3081 +N:Mcknight;Luis;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Janel York +IMPP:sip:janel@sip.linphone.org +NOTE:Duis at zzril aliquip molestie. +ADR:;;1583 Oakes Parkway;Arcadia;PA;15712; +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Mullins;Bradly;;; +ADR:;;8187 Waverly Circle;Warwick;RI;02889; +FN:Bradly Mullins +IMPP:sip:bradly@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Minter;Gaston;;; +NOTE:Nulla luptatumzzril dignissim elitsed. +TEL:tel:(415)304-7692 +FN:Gaston Minter +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Marie Sena +N:Sena;Marie;;; +BDAY:19510523 +TEL:tel:(845)670-5951 +ORG:Telecom Building +GENDER:O +EMAIL:marie@vulputateutwisi.info +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:refugio@sip.linphone.org +N:Van;Refugio;;; +GENDER:U +BDAY:19501221 +TEL:tel:(317)120-5160 +EMAIL:refugio@illumex.eu +FN:Refugio Van +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Carl Burge +EMAIL:c.burge@minimutwisi.edu +N:Burge;Carl;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Augue elitsed nulla veniamquis vulputate et duis facilisis dolor nisl in ex invulputate. +ORG:Industries Direct Telecom +TEL:tel:(817)178-1296 +BDAY:19690919 +FN:Estella Peterman +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Accumsan elitsed erat vulputate sit. +TEL:tel:(865)523-8660 +ORG:Bell Star West +EMAIL:rita.hadley@ullamcorperdolore.eu +IMPP:sip:rita@sip.linphone.org +FN:Rita Hadley +BDAY:19850205 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Max Atlantic +EMAIL:sal@molestiedoloremagna.info +FN:Sal Downes +ADR:;;6714 Misty Creek Trail;Rochelle;VA;22738; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:phillis@sip.linphone.org +NOTE:Iusto ut augue et consectetuer molestie te et zzril etaccumsan consectetuer ullamcorper consectetuer. +BDAY:19441020 +FN:Phillis Corrigan +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(702)725-2797 +BDAY:19750726 +GENDER:F +EMAIL:b.thiel@eratte.net +ADR:;;5846 Long Oak Street;Sheldon;WI;54766; +FN:Brandy Thiel +IMPP:sip:brandy@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +FN:Chance Mccants +TEL:tel:(775)234-5923 +BDAY:19850112 +NOTE:Minim facilisi sit eros augue. +ORG:Internet Internet +IMPP:sip:chance@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:M +ADR:;;1880 Capital Cove;Rushville;IN;46173; +FN:Rodrick Carrion +IMPP:sip:rodrick@sip.linphone.org +EMAIL:r.carrion@velut.info +ORG:Virtual People Federated +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:wilhelmina@sip.linphone.org +FN:Wilhelmina Chapa +GENDER:N +BDAY:19950621 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;2640 Maple Shadow Circle;Jonestown;PA;17038; +FN:Christine Crump +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +N:Partin;Brad;;; +NOTE:Consequatvel eu euismod aliquip dignissim feugait consequat. +TEL:tel:(985)818-4990 +ADR:;;1449 Nova Scotia Lane;Clear Lake;SD;57226; +FN:Brad Partin +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;501 Pond View Circle;New Market;TN;37820; +EMAIL:nicholas.estrada@consequatdelenit.org +N:Estrada;Nicholas;;; +BDAY:19501026 +NOTE:Praesent volutpat feugiat nulla consequatvel blandit. +GENDER:O +FN:Nicholas Estrada +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(202)249-3991 +IMPP:sip:adam@sip.linphone.org +N:Loper;Adam;;; +FN:Adam Loper +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:domingo@minimeufeugiat.org +N:Herman;Domingo;;; +IMPP:sip:domingo@sip.linphone.org +FN:Domingo Herman +ORG:Contract Power +BDAY:19350114 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:dan@iriuredolortincidunt.gov +TEL:tel:(262)839-5720 +NOTE:Zzril consequatvel vel luptatum. +ADR:;;3324 Silkwood Trail;Haymarket;VA;20168; +FN:Dan Picard +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:a.jansen@diamnulla.net +NOTE:In facilisis facilisi nulla. +FN:Alberta Jansen +TEL:tel:(817)811-3555 +BDAY:19721227 +GENDER:O +ORG:Software Research +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;6276 Grisby Circle;West Glover;VT;05875; +NOTE:Esse hendrerit dolore suscipit. +IMPP:sip:omer@sip.linphone.org +FN:Omer Callaghan +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:M +ORG:Solutions Software Systems +IMPP:sip:peter@sip.linphone.org +ADR:;;1756 Panorama Cove;East Earl;PA;17519; +FN:Peter Beebe +TEL:tel:(831)357-5575 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(701)372-5913 +FN:Roselyn Sutherland +ADR:;;1922 Trotter Drive;Montmorenci;IN;47962; +IMPP:sip:roselyn@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Direct Provider Technology +EMAIL:m.stroup@veroad.tv +GENDER:N +BDAY:19500408 +FN:Mandy Stroup +N:Stroup;Mandy;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:malcolm@accumsanautem.org +TEL:tel:(814)753-1865 +IMPP:sip:malcolm@sip.linphone.org +NOTE:Te in praesent quis aliquip feugait praesent esse feugiat duis. +N:Ayers;Malcolm;;; +FN:Malcolm Ayers +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +EMAIL:d.baumgardner@loremillum.com +N:Baumgardner;Dion;;; +ADR:;;2975 Cobblestone Cove;Noxon;MT;59853; +TEL:tel:(419)414-3163 +FN:Dion Baumgardner +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Sandoval;Tina;;; +ORG:Net Star Solutions +FN:Tina Sandoval +GENDER:F +ADR:;;4898 Belfort Trail;Mingo;OH;43047; +IMPP:sip:tina@sip.linphone.org +NOTE:Autem duis nislut duis nostrud molestie et eros nulla blandit consequat diam. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Bannister;Valarie;;; +FN:Valarie Bannister +GENDER:F +ADR:;;6156 Hazelton Avenue;Malabar;FL;32950; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;5385 Oakridge Lane;Glendale;CA;91206; +FN:Melvin Quinlan +N:Quinlan;Melvin;;; +NOTE:Velit illum dignissim facilisi esse dolore exerci augue ea dolore facilisi. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19481011 +FN:Lorna Singh +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(574)677-1641 +N:Ricks;Merrill;;; +GENDER:N +IMPP:sip:merrill@sip.linphone.org +FN:Merrill Ricks +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Christoper Niles +ORG:Alpha Star Hardware +EMAIL:christoper@eaquis.gov +IMPP:sip:christoper@sip.linphone.org +ADR:;;6344 Saint Marys Parkway;Los Alamitos;CA;90721; +NOTE:Autem at qui facilisis dolore Utwisi dolore exerci dolore duis autem at veniam. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Systems Star Speed +BDAY:19530720 +TEL:tel:(270)835-6822 +FN:Odis Currier +IMPP:sip:odis@sip.linphone.org +N:Currier;Odis;;; +EMAIL:odis@nulladignissim.tv +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +FN:Judith Lightfoot +ORG:Net Bell +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Alfredo Mata +EMAIL:alfredo.mata@duisamet.net +TEL:tel:(573)163-1426 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +FN:Long Grigsby +ORG:People Provider Frontier +TEL:tel:(907)143-6709 +IMPP:sip:long@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Dara Minnick +EMAIL:d.minnick@veniamerat.net +ORG:Star Construction +NOTE:Et veniamquis eufeugiat aliquip lorem vel esse Utwisi delenit nulla nostrud nonummy velit. +IMPP:sip:dara@sip.linphone.org +N:Minnick;Dara;;; +GENDER:N +ADR:;;2585 Woffington Street;Grand Junction;CO;81505; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Carroll Giordano +ADR:;;8151 Goswell Circle;Peoria;IL;61603; +IMPP:sip:carroll@sip.linphone.org +EMAIL:carroll@esseiusto.net +BDAY:19640315 +GENDER:N +N:Giordano;Carroll;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Ammons;Tisha;;; +GENDER:O +FN:Tisha Ammons +ORG:Construction Electronic +ADR:;;7971 Oak Trail;Park Ridge;NJ;07656; +TEL:tel:(470)631-3203 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;8829 Rock Avenue;Farmersville;CA;93223; +FN:Jeromy Ervin +GENDER:U +N:Ervin;Jeromy;;; +BDAY:19550614 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;8296 Kelman Circle;Carlstadt;NJ;07072; +N:Manns;Homer;;; +FN:Homer Manns +EMAIL:homer.manns@loremconsequat.us +NOTE:Diam exerci veniam doloremagna facilisis tation. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;2243 Rice Drive;Bedias;TX;77831; +TEL:tel:(903)248-3314 +GENDER:O +FN:Catalina Crabtree +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:julia.nowak@consequatea.tv +TEL:tel:(717)275-6952 +FN:Julia Nowak +GENDER:O +ADR:;;803 Stout Street;Fort Lauderdale;FL;33323; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Delma Chester +GENDER:F +ORG:Advanced Future Alpha +ADR:;;2794 Saint Francis Street;Banner;MS;38913; +IMPP:sip:delma@sip.linphone.org +TEL:tel:(505)315-5956 +N:Chester;Delma;;; +EMAIL:delma@adipiscingdolor.us +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Velit blandit et in velit commodoconsequat vel tincidunt. +N:Daniels;Tommie;;; +ADR:;;1053 Hidden Valley Circle;Walnut Springs;TX;76690; +BDAY:19670303 +GENDER:U +FN:Tommie Daniels +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:blair@sip.linphone.org +FN:Blair Leone +BDAY:19660616 +ORG:Internet Interactive Network +NOTE:Ex vero facilisi dignissim suscipit nulla esse odio. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Lamar Horsley +GENDER:N +ORG:Net Solutions +N:Horsley;Lamar;;; +ADR:;;6941 Willard Lane;Mount Victory;OH;43340; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Sydney Beeson +EMAIL:sydney.beeson@autemvel.info +ADR:;;3404 Waverly Circle;Tolleson;AZ;85353; +IMPP:sip:sydney@sip.linphone.org +N:Beeson;Sydney;;; +TEL:tel:(802)733-7172 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Federated Technology Data +EMAIL:issac.snowden@autemad.info +BDAY:19960608 +GENDER:M +FN:Issac Snowden +ADR:;;9018 Brick Trail;Carrollton;TX;75011; +NOTE:Nostrud nostrud et lobortis feugait quis laoreet volutpat et esse eros odio augue ad. +TEL:tel:(917)417-2068 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:myles.devore@invulputatedolore.gov +IMPP:sip:myles@sip.linphone.org +NOTE:At autem at nislut hendrerit exerci blandit iusto ad. +ADR:;;3403 Deauville Trail;Lobeco;SC;29931; +FN:Myles Devore +ORG:West Telecom Power +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +NOTE:Facilisi iriuredolor ex illum duis esse duis hendrerit delenit suscipit elitsed odio duis vero. +FN:Trinidad Heaton +ORG:Application Atlantic North +IMPP:sip:trinidad@sip.linphone.org +TEL:tel:(859)538-2730 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19350803 +EMAIL:t.bergeron@duiset.org +GENDER:M +ADR:;;7998 Egerton Circle;Wellsville;OH;43968; +IMPP:sip:taylor@sip.linphone.org +N:Bergeron;Taylor;;; +ORG:Contract Vision Galaxy +NOTE:Praesent feugiat facilisis adipiscing dignissim facilisi blandit suscipit. +TEL:tel:(424)394-4266 +FN:Taylor Bergeron +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Data Future +IMPP:sip:melvin@sip.linphone.org +FN:Melvin Henson +EMAIL:melvin@nullaeum.gov +TEL:tel:(616)862-2501 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:M +N:Galvin;August;;; +IMPP:sip:august@sip.linphone.org +ADR:;;3716 Justen Way;Lambsburg;VA;24351; +BDAY:19651007 +NOTE:Wisi nostrud autem esse ex minim. +ORG:East Source Star +TEL:tel:(484)291-9887 +FN:August Galvin +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Valentina Ayers +IMPP:sip:valentina@sip.linphone.org +BDAY:19370507 +ADR:;;41 Rosehaven Cove;Leesburg;FL;34748; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Emilie Scott +IMPP:sip:emilie@sip.linphone.org +NOTE:Dolore ut in nonummy vulputate consequat velit illum nislut exerci velit esse ut. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;5005 Soboda Cove;Vacaville;CA;95688; +TEL:tel:(479)292-1138 +EMAIL:lupe.wells@feugaitex.gov +FN:Lupe Wells +ORG:Atlantic Systems Application +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Lindsey Tierney +BDAY:19700528 +N:Tierney;Lindsey;;; +IMPP:sip:lindsey@sip.linphone.org +ADR:;;255 Ravensdale Trail;Shiloh;NC;27974; +EMAIL:lindsey.tierney@dignissimnulla.info +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:d.naquin@consequatvel.net +TEL:tel:(404)455-8239 +FN:Dylan Naquin +NOTE:Facilisis nisl dignissim nulla at velit facilisi blandit elitsed te nostrud feugait doloremagna. +N:Naquin;Dylan;;; +GENDER:O +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:h.kohl@lobortistationullamcorper.gov +ADR:;;8148 Nightingale Drive;Pleasanton;TX;78064; +FN:Holli Kohl +N:Kohl;Holli;;; +IMPP:sip:holli@sip.linphone.org +ORG:Innovation Provider Software +TEL:tel:(757)347-2890 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(505)356-8068 +FN:Lilly Ouellette +NOTE:Delenit qui velit dolore illum exerci nostrud nonummy iustoodio lobortis. +GENDER:O +ADR:;;3985 Abbott Way;Cottonwood;AZ;86326; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Analysis Hill +TEL:tel:(606)118-9656 +IMPP:sip:erin@sip.linphone.org +GENDER:U +FN:Erin Harding +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:N +ADR:;;9508 Stone Mill Circle;Peoria;IL;61634; +FN:Natalia Drury +N:Drury;Natalia;;; +EMAIL:natalia.drury@doloremagnaeuismod.com +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:East Architecture Adventure +NOTE:Duis dignissim augue suscipit hendrerit. +N:Massie;Allen;;; +FN:Allen Massie +GENDER:M +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Elliott;Nan;;; +ADR:;;1252 Burlington Parkway;Washington;DC;20404; +IMPP:sip:nan@sip.linphone.org +TEL:tel:(614)501-2359 +FN:Nan Elliott +EMAIL:n.elliott@aliquamveniam.edu +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Dowdy;Leo;;; +GENDER:M +IMPP:sip:leo@sip.linphone.org +FN:Leo Dowdy +EMAIL:leo.dowdy@nostruddiam.org +NOTE:Facilisi iriuredolor iusto diam tation duis enim at duis dolore facilisis minim. +ORG:Hardware Hill +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;7608 Great Oaks Way;Toledo;OH;43609; +GENDER:U +FN:Kimberly Langlois +BDAY:19741127 +NOTE:Hendrerit aliquam suscipit feugait duis qui iustoodio dolore. +N:Langlois;Kimberly;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Autem augue blandit ut quis enim iriure. +IMPP:sip:cody@sip.linphone.org +FN:Cody Callahan +ADR:;;4132 Isleton Way;Charlotte;NC;28281; +N:Callahan;Cody;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:O +EMAIL:tillie.horowitz@commodoat.info +IMPP:sip:tillie@sip.linphone.org +TEL:tel:(641)311-8633 +N:Horowitz;Tillie;;; +FN:Tillie Horowitz +NOTE:Lorem nulla vel enim consequatvel et. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Pilar Franz +N:Franz;Pilar;;; +ORG:Digital Solutions Signal +TEL:tel:(804)818-5486 +ADR:;;2948 Judd Trail;Rociada;NM;87742; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;8412 Hollyhock Cove;Ocala;FL;34470; +EMAIL:cleo.osgood@laoreetaugue.net +FN:Cleo Osgood +GENDER:O +ORG:Net Vision North +IMPP:sip:cleo@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(445)903-1629 +N:Fink;Marylou;;; +BDAY:19880311 +NOTE:Illum nulla volutpat feugait te quis feugiat iriuredolor duis eum. +ADR:;;1937 Peabody Circle;Gaithersburg;MD;20884; +FN:Marylou Fink +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;814 Water Lane;Wentworth;SD;57075; +FN:Adrianne Coffey +EMAIL:a.coffey@lobortissuscipit.edu +N:Coffey;Adrianne;;; +BDAY:19771025 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:leila.timmerman@tinciduntiriure.eu +NOTE:Facilisi at aliquip at at Utwisi blandit blandit accumsan duis nulla elitsed quis consectetuer. +ORG:Max North General +ADR:;;3545 Germantown Circle;Nevada;IA;50201; +N:Timmerman;Leila;;; +FN:Leila Timmerman +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:cari@sip.linphone.org +FN:Cari Shumaker +ORG:Building Software Net +BDAY:19730326 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:dixie@sip.linphone.org +N:Spalding;Dixie;;; +FN:Dixie Spalding +ORG:Design Universal Systems +NOTE:Veniam autem iriuredolor dolore velit. +ADR:;;6361 Kimbrough Grove Trail;Brooklyn;NY;11239; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(623)204-1369 +N:Harness;Pierre;;; +FN:Pierre Harness +ADR:;;8289 Cherrybark Trail;Glencoe;IL;60022; +ORG:Interactive Architecture Atlantic +NOTE:Suscipit et et et duis eufeugiat duis lobortis dolore vel. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Phillip Mock +GENDER:M +ADR:;;7944 Lakeside Circle;Monroeville;PA;15146; +NOTE:Nostrud etaccumsan praesent suscipit vel eu molestie velit ut hendrerit tincidunt. +TEL:tel:(251)981-4291 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Mercer;Columbus;;; +GENDER:M +NOTE:Feugait vero aliquip facilisis luptatum illum hendrerit suscipit. +FN:Columbus Mercer +END:VCARD +BEGIN:VCARD +VERSION:4.0 +NOTE:Facilisi eros autem velit volutpat at at zzril et. +FN:Alicia Rosario +TEL:tel:(812)170-6637 +BDAY:19741228 +N:Rosario;Alicia;;; +EMAIL:alicia.rosario@quisvolutpat.gov +IMPP:sip:alicia@sip.linphone.org +ORG:Data East +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;8041 Wyndhurst Trail;Houston;TX;77043; +IMPP:sip:darryl@sip.linphone.org +ORG:Future Solutions +FN:Darryl Adler +NOTE:Augue invulputate in minim eum vel tation at iriure. +N:Adler;Darryl;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:F +NOTE:Feugait te adipiscing wisi facilisi eros. +ORG:Galaxy Speed Solutions +IMPP:sip:lula@sip.linphone.org +ADR:;;8420 Jamaca Circle;Vancouver;WA;98684; +FN:Lula Harness +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;5937 Overlook Circle;Paul Smiths;NY;12970; +FN:Diane Joseph +NOTE:Duis vero ex facilisi qui hendrerit facilisis autem. +N:Joseph;Diane;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Dominic Jordan +TEL:tel:(336)346-2767 +N:Jordan;Dominic;;; +BDAY:19600127 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Tony Back +ADR:;;8733 Foxgate Cove;Oak Bluffs;MA;02557; +BDAY:19960426 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Jolene Black +NOTE:Eros autem in vel esse tincidunt ad laoreet qui minim ipsum. +EMAIL:j.black@feugaitvero.gov +BDAY:19911030 +IMPP:sip:jolene@sip.linphone.org +TEL:tel:(337)144-3107 +ADR:;;8758 Lydia Street;Forsyth;MT;59327; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Charleen Begay +GENDER:U +NOTE:Aliquip eu vulputate nulla facilisis illum blandit blandit dolore hendrerit. +N:Begay;Charleen;;; +ADR:;;6130 Hobbits Glen Avenue;Tallman;NY;10982; +EMAIL:charleen@inconsequat.info +BDAY:19710222 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(907)209-2611 +FN:Xavier Vanhoose +ORG:Max Pacific +EMAIL:x.vanhoose@nibhvel.com +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Samuel Marshall +N:Marshall;Samuel;;; +GENDER:N +BDAY:19640301 +NOTE:Ad nulla minim nulla suscipit vel tincidunt augue. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;9995 Station Hill Circle;Mount Gilead;OH;43338; +BDAY:19871228 +NOTE:Tation veniamquis luptatumzzril nibh facilisis duis ullamcorper nisl consequat suscipit accumsan suscipit. +ORG:Data Design +EMAIL:j.ralston@autemsuscipit.edu +FN:Janis Ralston +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(270)820-9211 +FN:Migdalia Rash +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ORG:Vision Future Solutions +NOTE:Qui autem in iriuredolor vel amet dolor invulputate. +ADR:;;5604 Queensbury Way;Canton;OH;44720; +TEL:tel:(610)121-8396 +IMPP:sip:eugenia@sip.linphone.org +FN:Eugenia Pantoja +END:VCARD +BEGIN:VCARD +VERSION:4.0 +GENDER:M +BDAY:19700608 +IMPP:sip:alfonzo@sip.linphone.org +FN:Alfonzo Tompkins +TEL:tel:(475)485-9104 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(763)202-1504 +EMAIL:chong@eumeros.us +GENDER:N +NOTE:Eum etaccumsan exerci et dignissim aliquip ipsum lorem. +ORG:Star Universal Consulting +BDAY:19580709 +FN:Chong Mabry +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:silas@autemeros.edu +FN:Silas Leal +TEL:tel:(412)257-8210 +ADR:;;3212 Grove Lake Trail;Kirkland;AZ;86332; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Latasha Crowe +IMPP:sip:latasha@sip.linphone.org +ORG:Design Technology Analysis +END:VCARD +BEGIN:VCARD +VERSION:4.0 +TEL:tel:(219)537-6700 +EMAIL:leta@blanditsit.info +ORG:Adventure Advanced Telecom +FN:Leta Mccloskey +N:Mccloskey;Leta;;; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Allison;Alejandro;;; +ORG:Innovation Source Net +EMAIL:alejandro@minimodio.eu +GENDER:O +FN:Alejandro Allison +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Asher;Freddy;;; +GENDER:M +FN:Freddy Asher +NOTE:Vel eufeugiat in eum. +EMAIL:freddy@esseiustoodio.gov +ADR:;;4137 Carlingford Way;Sheldon Springs;VT;05485; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;8996 Fairmeadows Trail;Maybell;CO;81640; +GENDER:M +ORG:Universal Advanced Consulting +IMPP:sip:mack@sip.linphone.org +FN:Mack Lombard +TEL:tel:(775)827-4643 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +N:Spearman;Melinda;;; +ADR:;;3906 Rich Hill Way;Green Spring;WV;26722; +FN:Melinda Spearman +ORG:Medicine Vision Universal +GENDER:O +IMPP:sip:melinda@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19840316 +EMAIL:kesha.tuggle@essefeugait.org +N:Tuggle;Kesha;;; +ORG:South Studio Vision +IMPP:sip:kesha@sip.linphone.org +FN:Kesha Tuggle +TEL:tel:(865)414-7674 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +IMPP:sip:eugenia@sip.linphone.org +FN:Eugenia Lucas +BDAY:19521229 +EMAIL:eugenia@veroesse.eu +ORG:Future Studio Direct +TEL:tel:(330)135-6449 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +ADR:;;550 Palomino Trail;Letcher;SD;57359; +NOTE:Velit ea vel eufeugiat nulla. +BDAY:19470117 +FN:Cecile Laws +ORG:Telecom Net Analysis +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19730822 +EMAIL:a.gaylord@consequatduis.org +FN:Arturo Gaylord +NOTE:Duis dolore enim te feugait. +IMPP:sip:arturo@sip.linphone.org +END:VCARD +BEGIN:VCARD +VERSION:4.0 +EMAIL:r.orellana@odiotation.org +ADR:;;2672 Fiddlers Elbow Circle;Mcgregor;MN;55760; +FN:Rosalina Orellana +TEL:tel:(817)292-2224 +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Jeffrey Broome +ORG:Internet Vision Adventure +N:Broome;Jeffrey;;; +EMAIL:j.broome@nullaautem.org +ADR:;;322 Oakland Trail;Laceys Spring;AL;35754; +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Ricardo Zarate +ADR:;;7882 Somerset Lane;Rose;NE;68772; +EMAIL:r.zarate@eufeugiatesse.org +NOTE:Dolore in euismod esse vero. +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:Jae Wilber +ORG:Contract Alpha Speed +END:VCARD +BEGIN:VCARD +VERSION:4.0 +BDAY:19640214 +N:Kimbrough;Deidra;;; +FN:Deidra Kimbrough +ORG:Pacific Bell +TEL:tel:(413)543-7430 +END:VCARD diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index e7931c7c7..81686c230 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -20,6 +20,8 @@ #include "private.h" #include "liblinphone_tester.h" +#include + static char *create_filepath(const char *dir, const char *filename, const char *ext) { return ms_strdup_printf("%s/%s.%s", dir, filename, ext); } @@ -52,8 +54,25 @@ static void linphone_vcard_import_export_friends_test(void) { linphone_core_manager_destroy(manager); } +static void linphone_vcard_import_a_lot_of_friends_test(void) { + LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + char *import_filepath = bc_tester_res("common/thousand_vcards.vcf"); + clock_t start, end; + double elapsed = 0; + + start = clock(); + linphone_core_import_friends_from_vcard4_file(manager->lc, import_filepath); + end = clock(); + + elapsed = (double)(end - start); + ms_error("Imported a thousand of friends in %f seconds", elapsed / CLOCKS_PER_SEC); + BC_ASSERT_TRUE(elapsed < 2500000); // 2.5 seconds + linphone_core_manager_destroy(manager); +} + test_t vcard_tests[] = { { "Import / Export friends from vCards", linphone_vcard_import_export_friends_test }, + { "Import a lot of friends from vCards", linphone_vcard_import_a_lot_of_friends_test }, }; test_suite_t vcard_test_suite = { From caf26c0b4240f5799f4ace1b49a37692b04485f8 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 17 Dec 2015 15:18:56 +0100 Subject: [PATCH 014/121] Improved a few more things regarding friends and vcards --- coreapi/friend.c | 33 ++++++++++++++++++++++++--------- coreapi/linphonecore.c | 1 + tester/vcard_tester.c | 6 ++++-- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index 44a764718..bc0341f15 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -200,34 +200,44 @@ void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char int linphone_friend_set_address(LinphoneFriend *lf, const LinphoneAddress *addr){ LinphoneAddress *fr = linphone_address_clone(addr); + LinphoneVCard *vcard = NULL; linphone_address_clean(fr); if (lf->uri != NULL) linphone_address_destroy(lf->uri); lf->uri = fr; + vcard = linphone_friend_get_vcard(lf); + if (vcard) { + linphone_vcard_edit_main_sip_address(vcard, linphone_address_as_string_uri_only(fr)); + } + return 0; } int linphone_friend_set_name(LinphoneFriend *lf, const char *name){ LinphoneAddress *fr = lf->uri; LinphoneVCard *vcard = NULL; - - if (fr == NULL) { - ms_error("linphone_friend_set_address() must be called before linphone_friend_set_name()."); - return -1; - } - linphone_address_set_display_name(fr, name); + bool_t vcard_created = FALSE; vcard = linphone_friend_get_vcard(lf); if (!vcard) { linphone_friend_create_vcard(lf, name); vcard = linphone_friend_get_vcard(lf); - } + vcard_created = TRUE; + } if (vcard) { linphone_vcard_set_full_name(vcard, name); - linphone_vcard_edit_main_sip_address(vcard, linphone_address_as_string_uri_only(fr)); + if (fr && vcard_created) { // SIP address wasn't set yet, let's do it + linphone_vcard_edit_main_sip_address(vcard, linphone_address_as_string_uri_only(fr)); + } } + if (!fr) { + ms_warning("linphone_friend_set_address() must be called before linphone_friend_set_name() to be able to set display name."); + return -1; + } + linphone_address_set_display_name(fr, name); + return 0; } @@ -531,6 +541,10 @@ void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) { } void linphone_core_import_friend(LinphoneCore *lc, LinphoneFriend *lf) { + if (!lf->uri) { + return; // Do not abort if friend doesn't have a SIP URI + } + lf->lc = lc; lc->friends = ms_list_append(lc->friends, linphone_friend_ref(lf)); if (linphone_core_ready(lc)) linphone_friend_apply(lf, lc); else lf->commit = TRUE; @@ -833,7 +847,8 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * LinphoneVCard *vcard = (LinphoneVCard *)vcards->data; LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); if (lf) { - linphone_core_add_friend(lc, lf); + linphone_core_import_friend(lc, lf); + linphone_friend_unref(lf); count++; } vcards = ms_list_next(vcards); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 34a5f6717..271570951 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -6424,6 +6424,7 @@ static void linphone_core_uninit(LinphoneCore *lc) if (lc->chat_db_file){ ms_free(lc->chat_db_file); } + linphone_core_free_payload_types(lc); if (lc->supported_formats) ms_free(lc->supported_formats); linphone_core_message_storage_close(lc); diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 81686c230..46efdc0f2 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -59,14 +59,16 @@ static void linphone_vcard_import_a_lot_of_friends_test(void) { char *import_filepath = bc_tester_res("common/thousand_vcards.vcf"); clock_t start, end; double elapsed = 0; + const MSList *friends = NULL; start = clock(); linphone_core_import_friends_from_vcard4_file(manager->lc, import_filepath); end = clock(); + friends = linphone_core_get_friend_list(manager->lc); elapsed = (double)(end - start); - ms_error("Imported a thousand of friends in %f seconds", elapsed / CLOCKS_PER_SEC); - BC_ASSERT_TRUE(elapsed < 2500000); // 2.5 seconds + ms_error("Imported a thousand of vCards (only %i friends with SIP address found) in %f seconds", ms_list_size(friends), elapsed / CLOCKS_PER_SEC); + BC_ASSERT_TRUE(elapsed < 5000000); // 5 seconds linphone_core_manager_destroy(manager); } From bab0c39c6f690ef6f6e5df9988a9b87d00e855d5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 17 Dec 2015 15:25:31 +0100 Subject: [PATCH 015/121] Improved import time by optimizing moment when friends are saved in rc file --- coreapi/friend.c | 42 ++++++++++++++++++++++++------------------ tester/vcard_tester.c | 2 +- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index bc0341f15..21d218513 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -467,47 +467,51 @@ void linphone_friend_update_subscribes(LinphoneFriend *fr, LinphoneProxyConfig * } } -void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){ +void linphone_friend_save(LinphoneFriend *fr, LinphoneCore *lc) { + linphone_core_write_friends_config(lc); +} + +void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc) { LinphonePresenceModel *model; - if (fr->uri==NULL) { + if (!fr->uri) { ms_warning("No sip url defined."); return; } - linphone_core_write_friends_config(lc); - - if (fr->inc_subscribe_pending){ - switch(fr->pol){ + if (fr->inc_subscribe_pending) { + switch(fr->pol) { case LinphoneSPWait: model = linphone_presence_model_new_with_activity(LinphonePresenceActivityOther, "Waiting for user acceptance"); - linphone_friend_notify(fr,model); + linphone_friend_notify(fr, model); linphone_presence_model_unref(model); break; case LinphoneSPAccept: - if (fr->lc!=NULL) - linphone_friend_notify(fr,fr->lc->presence_model); + if (fr->lc) + linphone_friend_notify(fr, fr->lc->presence_model); break; case LinphoneSPDeny: - linphone_friend_notify(fr,NULL); + linphone_friend_notify(fr, NULL); break; } - fr->inc_subscribe_pending=FALSE; + fr->inc_subscribe_pending = FALSE; + } + if (fr->lc) { + linphone_friend_update_subscribes(fr, NULL, linphone_core_should_subscribe_friends_only_when_registered(fr->lc)); } - if (fr->lc) - linphone_friend_update_subscribes(fr,NULL,linphone_core_should_subscribe_friends_only_when_registered(fr->lc)); ms_message("linphone_friend_apply() done."); - lc->bl_refresh=TRUE; - fr->commit=FALSE; + lc->bl_refresh = TRUE; + fr->commit = FALSE; } void linphone_friend_edit(LinphoneFriend *fr){ } void linphone_friend_done(LinphoneFriend *fr){ - ms_return_if_fail(fr!=NULL); - if (fr->lc==NULL) return; - linphone_friend_apply(fr,fr->lc); + ms_return_if_fail(fr); + if (!fr->lc) return; + linphone_friend_apply(fr, fr->lc); + linphone_friend_save(fr, fr->lc); } LinphoneFriend * linphone_core_create_friend(LinphoneCore *lc) { @@ -533,6 +537,7 @@ void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) { return; } linphone_core_import_friend(lc, lf); + linphone_friend_save(lf, lc); if (ms_list_find(lc->subscribers, lf)) { /*if this friend was in the pending subscriber list, now remove it from this list*/ lc->subscribers = ms_list_remove(lc->subscribers, lf); @@ -853,6 +858,7 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * } vcards = ms_list_next(vcards); } + linphone_core_write_friends_config(lc); return count; } diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 46efdc0f2..a7294c1c4 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -68,7 +68,7 @@ static void linphone_vcard_import_a_lot_of_friends_test(void) { friends = linphone_core_get_friend_list(manager->lc); elapsed = (double)(end - start); ms_error("Imported a thousand of vCards (only %i friends with SIP address found) in %f seconds", ms_list_size(friends), elapsed / CLOCKS_PER_SEC); - BC_ASSERT_TRUE(elapsed < 5000000); // 5 seconds + BC_ASSERT_TRUE(elapsed < 1500000); // 1.5 seconds linphone_core_manager_destroy(manager); } From 56db674e381871665c9133253004ec86608936b9 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 17 Dec 2015 16:44:55 +0100 Subject: [PATCH 016/121] Started linphone friends database storage --- configure.ac | 36 ++++++ coreapi/call_log.c | 6 +- coreapi/friend.c | 248 +++++++++++++++++++++++++++++++++++---- coreapi/linphonecore.c | 11 +- coreapi/linphonefriend.h | 16 +++ coreapi/private.h | 10 ++ 6 files changed, 302 insertions(+), 25 deletions(-) diff --git a/configure.ac b/configure.ac index 7f2b95aad..2bd3f8de8 100644 --- a/configure.ac +++ b/configure.ac @@ -980,6 +980,41 @@ fi AM_CONDITIONAL(BUILD_CALL_LOGS_STORAGE, test x$enable_call_logs_storage = xtrue) +AC_ARG_ENABLE(friends-db-storage, + [AS_HELP_STRING([--enable-friends-db-storage=[yes/no]], [Turn on compilation of friends database storage (default=auto)])], + [case "${enableval}" in + yes) enable_friends_db_storage=true ;; + no) enable_friends_db_storage=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-friends-db-storage) ;; + esac], + [enable_friends_db_storage=auto] +) + +if test x$enable_friends_db_storage != xfalse; then + PKG_CHECK_MODULES(SQLITE3,[sqlite3 >= 3.6.0],[found_sqlite=yes],[found_sqlite=no]) + if test "$found_sqlite" = "no"; then + dnl Check the lib presence in case the PKG-CONFIG version is not found + AC_CHECK_LIB(sqlite3, sqlite3_open, [SQLITE3_LIBS+=" -lsqlite3 "; found_sqlite=yes], [foo=bar]) + fi + if test "$found_sqlite" = "yes"; then + SQLITE3_CFLAGS+=" -DFRIENDS_SQL_STORAGE_ENABLED" + if test "$build_macos" = "yes" -o "$ios_found" = "yes"; then + SQLITE3_LIBS+=" -liconv" + fi + enable_friends_db_storage=true + else + if test x$enable_friends_db_storage = xtrue; then + AC_MSG_ERROR([sqlite3, required for friends database storage, not found]) + fi + enable_friends_db_storage=false + fi + + AC_SUBST(SQLITE3_CFLAGS) + AC_SUBST(SQLITE3_LIBS) +fi + +AM_CONDITIONAL(BUILD_FRIENDS_DB_STORAGE, test x$enable_friends_db_storage = xtrue) + PKG_CHECK_MODULES(BELLESIP, [belle-sip >= 1.4.0]) SIPSTACK_CFLAGS="$BELLESIP_CFLAGS" @@ -1139,6 +1174,7 @@ printf "* %-30s %s\n" "Console interface" $console_ui printf "* %-30s %s\n" "Tools" $build_tools printf "* %-30s %s\n" "Message storage" $enable_msg_storage printf "* %-30s %s\n" "Call logs storage" $enable_call_logs_storage +printf "* %-30s %s\n" "Friends db storage" $enable_friends_db_storage printf "* %-30s %s\n" "VCard support" $enable_vcard printf "* %-30s %s\n" "IM encryption" $lime printf "* %-30s %s\n" "uPnP support" $build_upnp diff --git a/coreapi/call_log.c b/coreapi/call_log.c index 2bf8d5b9f..fa3cd5fc8 100644 --- a/coreapi/call_log.c +++ b/coreapi/call_log.c @@ -345,7 +345,7 @@ static void linphone_create_table(sqlite3* db) { } } -void linphone_update_call_log_table(sqlite3* db) { +static void linphone_update_call_log_table(sqlite3* db) { char* errmsg=NULL; int ret; @@ -445,7 +445,7 @@ static int create_call_log(void *data, int argc, char **argv, char **colName) { return 0; } -void linphone_sql_request_call_log(sqlite3 *db, const char *stmt, MSList **list) { +static void linphone_sql_request_call_log(sqlite3 *db, const char *stmt, MSList **list) { char* errmsg = NULL; int ret; ret = sqlite3_exec(db, stmt, create_call_log, list, &errmsg); @@ -455,7 +455,7 @@ void linphone_sql_request_call_log(sqlite3 *db, const char *stmt, MSList **list) } } -int linphone_sql_request_generic(sqlite3* db, const char *stmt) { +static int linphone_sql_request_generic(sqlite3* db, const char *stmt) { char* errmsg = NULL; int ret; ret = sqlite3_exec(db, stmt, NULL, NULL, &errmsg); diff --git a/coreapi/friend.c b/coreapi/friend.c index 21d218513..8a7e5172f 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -26,6 +26,21 @@ #include "private.h" #include "lpconfig.h" +#ifdef FRIENDS_SQL_STORAGE_ENABLED +#ifndef _WIN32 +#if !defined(ANDROID) && !defined(__QNXNTO__) +# include +# include +# include +#endif +#else +#include +#endif + +#define MAX_PATH_SIZE 1024 +#include "sqlite3.h" +#endif + const char *linphone_online_status_to_string(LinphoneOnlineStatus ss){ const char *str=NULL; switch(ss){ @@ -128,11 +143,12 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){ } LinphoneFriend * linphone_friend_new(){ - LinphoneFriend *obj=belle_sip_object_new(LinphoneFriend); - obj->pol=LinphoneSPAccept; - obj->presence=NULL; - obj->subscribe=TRUE; + LinphoneFriend *obj = belle_sip_object_new(LinphoneFriend); + obj->pol = LinphoneSPAccept; + obj->presence = NULL; + obj->subscribe = TRUE; obj->vcard = NULL; + obj->storage_id = 0; return obj; } @@ -468,7 +484,11 @@ void linphone_friend_update_subscribes(LinphoneFriend *fr, LinphoneProxyConfig * } void linphone_friend_save(LinphoneFriend *fr, LinphoneCore *lc) { +#ifdef FRIENDS_SQL_STORAGE_ENABLED + linphone_core_store_friend_in_db(lc, fr); +#else linphone_core_write_friends_config(lc); +#endif } void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc) { @@ -555,14 +575,18 @@ void linphone_core_import_friend(LinphoneCore *lc, LinphoneFriend *lf) { else lf->commit = TRUE; } -void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* fl){ - MSList *el=ms_list_find(lc->friends,fl); - if (el!=NULL){ +void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* lf){ + MSList *el = ms_list_find(lc->friends, lf); + if (el != NULL) { linphone_friend_unref((LinphoneFriend*)el->data); - lc->friends=ms_list_remove_link(lc->friends,el); + lc->friends=ms_list_remove_link(lc->friends, el); +#ifdef FRIENDS_SQL_STORAGE_ENABLED + linphone_core_remove_friend_from_db(lc, lf); +#else linphone_core_write_friends_config(lc); - }else{ - ms_error("linphone_core_remove_friend(): friend [%p] is not part of core's list.",fl); +#endif + } else { + ms_error("linphone_core_remove_friend(): friend [%p] is not part of core's list.", lf); } } @@ -594,14 +618,16 @@ void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc){ } void linphone_friend_set_ref_key(LinphoneFriend *lf, const char *key){ - if (lf->refkey!=NULL){ + if (lf->refkey != NULL) { ms_free(lf->refkey); - lf->refkey=NULL; + lf->refkey = NULL; + } + if (key) { + lf->refkey = ms_strdup(key); + } + if (lf->lc) { + linphone_friend_save(lf, lf->lc); } - if (key) - lf->refkey=ms_strdup(key); - if (lf->lc) - linphone_core_write_friends_config(lf->lc); } const char *linphone_friend_get_ref_key(const LinphoneFriend *lf){ @@ -737,10 +763,12 @@ void linphone_friend_write_to_config_file(LpConfig *config, LinphoneFriend *lf, } } -void linphone_core_write_friends_config(LinphoneCore* lc) -{ +void linphone_core_write_friends_config(LinphoneCore* lc) { MSList *elem; int i; +#ifdef FRIENDS_SQL_STORAGE_ENABLED + return; +#endif if (! linphone_core_ready(lc)) return; /*dont write config when reading it !*/ for (elem=lc->friends,i=0; elem!=NULL; elem=ms_list_next(elem),i++){ linphone_friend_write_to_config_file(lc->config,(LinphoneFriend*)elem->data,i); @@ -853,12 +881,17 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); if (lf) { linphone_core_import_friend(lc, lf); - linphone_friend_unref(lf); +#ifdef FRIENDS_SQL_STORAGE_ENABLED + linphone_core_store_friend_in_db(lc, lf); +#endif + linphone_friend_unref(lf); count++; } vcards = ms_list_next(vcards); } +#ifndef FRIENDS_SQL_STORAGE_ENABLED linphone_core_write_friends_config(lc); +#endif return count; } @@ -895,4 +928,179 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneFriend, belle_sip_object_t, NULL, // clone _linphone_friend_marshall, FALSE -); \ No newline at end of file +); + +/******************************************************************************* + * SQL storage related functions * + ******************************************************************************/ + +#ifdef FRIENDS_SQL_STORAGE_ENABLED + +static void linphone_create_table(sqlite3* db) { + char* errmsg = NULL; + int ret; + ret = sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS friends (" + + ");",//TODO + 0, 0, &errmsg); + if (ret != SQLITE_OK) { + ms_error("Error in creation: %s.\n", errmsg); + sqlite3_free(errmsg); + } +} + +static void linphone_update_table(sqlite3* db) { + +} + +void linphone_core_friends_storage_init(LinphoneCore *lc) { + int ret; + const char *errmsg; + sqlite3 *db; + + linphone_core_friends_storage_close(lc); + + ret=_linphone_sqlite3_open(lc->friends_db_file, &db); + if (ret != SQLITE_OK) { + errmsg = sqlite3_errmsg(db); + ms_error("Error in the opening: %s.\n", errmsg); + sqlite3_close(db); + return; + } + + linphone_create_table(db); + linphone_update_table(db); + lc->friends_db = db; +} + +void linphone_core_friends_storage_close(LinphoneCore *lc) { + if (lc->friends_db) { + sqlite3_close(lc->friends_db); + lc->friends_db = NULL; + } +} + +/* DB layout: + * | 0 | storage_id + */ +static int create_friend(void *data, int argc, char **argv, char **colName) { + MSList **list = (MSList **)data; + LinphoneFriend *lf = NULL; + //TODO + *list = ms_list_append(*list, lf); + return 0; +} + +static int linphone_sql_request_friend(sqlite3* db, const char *stmt, MSList **list) { + char* errmsg = NULL; + int ret; + ret = sqlite3_exec(db, stmt, create_friend, list, &errmsg); + if (ret != SQLITE_OK) { + ms_error("linphone_sql_request: statement %s -> error sqlite3_exec(): %s.", stmt, errmsg); + sqlite3_free(errmsg); + } + return ret; +} + +static int linphone_sql_request_generic(sqlite3* db, const char *stmt) { + char* errmsg = NULL; + int ret; + ret = sqlite3_exec(db, stmt, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + ms_error("linphone_sql_request: statement %s -> error sqlite3_exec(): %s.", stmt, errmsg); + sqlite3_free(errmsg); + } + return ret; +} + +void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) { + if (lc && lc->friends_db) { + char *buf; + + if (lf->storage_id > 0) { + buf = sqlite3_mprintf("UPDATE friends SET WHERE (id = %i);", //TODO + lf->storage_id + ); + } else { + buf = sqlite3_mprintf("INSERT INTO friends VALUES(NULL);"); //TODO + } + linphone_sql_request_generic(lc->friends_db, buf); + sqlite3_free(buf); + + if (lf->storage_id == 0) { + lf->storage_id = sqlite3_last_insert_rowid(lc->friends_db); + } + } +} + +void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf) { + if (lc && lc->friends_db && lf->storage_id > 0) { + char *buf; + + buf = sqlite3_mprintf("DELETE FROM friends WHERE (id = %i);", + lf->storage_id + ); + linphone_sql_request_generic(lc->friends_db, buf); + sqlite3_free(buf); + + lf->storage_id = 0; + } +} + +MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) { + char *buf; + uint64_t begin,end; + MSList *result = NULL; + + if (!lc || lc->friends_db == NULL) return NULL; + + buf = sqlite3_mprintf("SELECT * FROM friends ORDER BY id"); + + begin = ortp_get_cur_time_ms(); + linphone_sql_request_friend(lc->friends_db, buf, &result); + end = ortp_get_cur_time_ms(); + ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin)); + sqlite3_free(buf); + + return result; +} + +#else + +void linphone_core_friends_storage_init(LinphoneCore *lc) { +} + +void linphone_core_friends_storage_close(LinphoneCore *lc) { +} + +void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) { +} + +void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf) { +} + +MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) { + return NULL; +} + +#endif + +void linphone_core_set_friends_database_path(LinphoneCore *lc, const char *path) { + if (lc->friends_db_file){ + ms_free(lc->friends_db_file); + lc->friends_db_file = NULL; + } + if (path) { + lc->friends_db_file = ms_strdup(path); + linphone_core_friends_storage_init(lc); + + linphone_core_migrate_friends_from_rc_to_db(lc); + } +} + +void linphone_core_migrate_friends_from_rc_to_db(LinphoneCore *lc) { +#ifndef FRIENDS_SQL_STORAGE_ENABLED + ms_warning("linphone has been compiled without sqlite, can't migrate friends"); + return; +#endif +} \ No newline at end of file diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 271570951..7538ca56a 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1364,10 +1364,17 @@ static void video_config_read(LinphoneCore *lc){ static void ui_config_read(LinphoneCore *lc) { - LinphoneFriend *lf; + LinphoneFriend *lf = NULL; +#ifdef FRIENDS_SQL_STORAGE_ENABLED + MSList *friends = linphone_core_fetch_friends_from_db(lc); + while (friends && friends->data) { + lf = friends->data; + friends = ms_list_next(friends); +#else int i; for (i=0;(lf=linphone_friend_new_from_config_file(lc,i))!=NULL;i++){ - linphone_core_add_friend(lc,lf); +#endif + linphone_core_add_friend(lc, lf); linphone_friend_unref(lf); } diff --git a/coreapi/linphonefriend.h b/coreapi/linphonefriend.h index cd194f1d1..74d452b33 100644 --- a/coreapi/linphonefriend.h +++ b/coreapi/linphonefriend.h @@ -457,6 +457,22 @@ LINPHONE_PUBLIC int linphone_core_import_friends_from_vcard4_file(LinphoneCore * */ LINPHONE_PUBLIC void linphone_core_export_friends_as_vcard4_file(LinphoneCore *lc, const char *vcard_file); +/** + * Sets the database filename where friends will be stored. + * If the file does not exist, it will be created. + * @ingroup initializing + * @param lc the linphone core + * @param path filesystem path +**/ +LINPHONE_PUBLIC void linphone_core_set_friends_database_path(LinphoneCore *lc, const char *path); + +/** + * Migrates the friends from the linphonerc to the database if not done yet + * @ingroup initializing + * @param lc the linphone core +**/ +LINPHONE_PUBLIC void linphone_core_migrate_friends_from_rc_to_db(LinphoneCore *lc); + /** * @} */ diff --git a/coreapi/private.h b/coreapi/private.h index 1bd69a40a..22c83669d 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -395,6 +395,11 @@ LinphoneFriend *linphone_find_friend_by_out_subscribe(MSList *l, SalOp *op); MSList *linphone_find_friend_by_address(MSList *fl, const LinphoneAddress *addr, LinphoneFriend **lf); bool_t linphone_core_should_subscribe_friends_only_when_registered(const LinphoneCore *lc); void linphone_core_update_friends_subscriptions(LinphoneCore *lc, LinphoneProxyConfig *cfg, bool_t only_when_registered); +void linphone_core_friends_storage_init(LinphoneCore *lc); +void linphone_core_friends_storage_close(LinphoneCore *lc); +void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf); +void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf); +MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc); int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, socklen_t *socklen, int default_port); @@ -654,6 +659,7 @@ struct _LinphoneFriend{ bool_t commit; bool_t initial_subscribes_sent; /*used to know if initial subscribe message was sent or not*/ LinphoneVCard *vcard; + unsigned int storage_id; }; BELLE_SIP_DECLARE_VPTR(LinphoneFriend); @@ -914,6 +920,10 @@ struct _LinphoneCore char *logs_db_file; #ifdef CALL_LOGS_STORAGE_ENABLED sqlite3 *logs_db; +#endif + char *friends_db_file; +#ifdef FRIENDS_SQL_STORAGE_ENABLED + sqlite3 *friends_db; #endif #ifdef BUILD_UPNP UpnpContext *upnp; From c1f11402a9505e07ea7e16eae2be314267f0289b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 17 Dec 2015 16:52:48 +0100 Subject: [PATCH 017/121] Prepared gtk application for friends' database storage --- coreapi/friend.c | 4 ++-- coreapi/linphonecore.c | 2 +- coreapi/private.h | 2 +- gtk/friendlist.c | 27 +++++++++++++++++++++++++++ gtk/linphone.h | 1 + gtk/main.c | 10 +++++++--- 6 files changed, 39 insertions(+), 7 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index 8a7e5172f..823b7fce8 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -1047,7 +1047,7 @@ void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf) { } } -MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) { +const MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) { char *buf; uint64_t begin,end; MSList *result = NULL; @@ -1079,7 +1079,7 @@ void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) { void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf) { } -MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) { +const MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) { return NULL; } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 7538ca56a..633c5c41f 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1366,7 +1366,7 @@ static void ui_config_read(LinphoneCore *lc) { LinphoneFriend *lf = NULL; #ifdef FRIENDS_SQL_STORAGE_ENABLED - MSList *friends = linphone_core_fetch_friends_from_db(lc); + const MSList *friends = linphone_core_fetch_friends_from_db(lc); while (friends && friends->data) { lf = friends->data; friends = ms_list_next(friends); diff --git a/coreapi/private.h b/coreapi/private.h index 22c83669d..009adb05b 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -399,7 +399,7 @@ void linphone_core_friends_storage_init(LinphoneCore *lc); void linphone_core_friends_storage_close(LinphoneCore *lc); void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf); void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf); -MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc); +const MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc); int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, socklen_t *socklen, int default_port); diff --git a/gtk/friendlist.c b/gtk/friendlist.c index 271d220e4..998a0d379 100644 --- a/gtk/friendlist.c +++ b/gtk/friendlist.c @@ -991,3 +991,30 @@ gboolean linphone_gtk_friend_list_motion_event_handler(GtkTreeView *friendlist, return FALSE; } +#define CONFIG_FILE ".linphone-friends.db" + +char *linphone_gtk_friends_storage_get_db_file(const char *filename){ + const int path_max=1024; + char *db_file=NULL; + + db_file=(char *)g_malloc(path_max*sizeof(char)); + if (filename==NULL) filename=CONFIG_FILE; + /*try accessing a local file first if exists*/ + if (access(CONFIG_FILE,F_OK)==0){ + snprintf(db_file,path_max,"%s",filename); + }else{ +#ifdef WIN32 + const char *appdata=getenv("APPDATA"); + if (appdata){ + snprintf(db_file,path_max,"%s\\%s",appdata,LINPHONE_CONFIG_DIR); + CreateDirectory(db_file,NULL); + snprintf(db_file,path_max,"%s\\%s\\%s",appdata,LINPHONE_CONFIG_DIR,filename); + } +#else + const char *home=getenv("HOME"); + if (home==NULL) home="."; + snprintf(db_file,path_max,"%s/%s",home,filename); +#endif + } + return db_file; +} \ No newline at end of file diff --git a/gtk/linphone.h b/gtk/linphone.h index f337770fb..ec7311cc9 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -116,6 +116,7 @@ LINPHONE_PUBLIC GtkWidget *linphone_gtk_make_tab_header(const gchar *label, cons char *linphone_gtk_message_storage_get_db_file(const char *filename); char *linphone_gtk_call_logs_storage_get_db_file(const char *filename); +char *linphone_gtk_friends_storage_get_db_file(const char* filename); LINPHONE_PUBLIC void linphone_gtk_close_assistant(void); LINPHONE_PUBLIC LinphoneCore *linphone_gtk_get_core(void); diff --git a/gtk/main.c b/gtk/main.c index ff71732c0..fb227f92e 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -252,7 +252,8 @@ gboolean linphone_gtk_get_audio_assistant_option(void){ } static void linphone_gtk_init_liblinphone(const char *config_file, - const char *factory_config_file, const char *chat_messages_db_file, const char *call_logs_db_file) { + const char *factory_config_file, const char *chat_messages_db_file, + const char *call_logs_db_file, const char *friends_db_file) { LinphoneCoreVTable vtable={0}; gchar *secrets_file=linphone_gtk_get_config_file(SECRETS_FILE); gchar *user_certificates_dir=linphone_gtk_get_config_file(CERTIFICATES_PATH); @@ -299,6 +300,7 @@ static void linphone_gtk_init_liblinphone(const char *config_file, } if (chat_messages_db_file) linphone_core_set_chat_database_path(the_core,chat_messages_db_file); if (call_logs_db_file) linphone_core_set_call_logs_database_path(the_core, call_logs_db_file); + if (friends_db_file) linphone_core_set_friends_database_path(the_core, friends_db_file); } LinphoneCore *linphone_gtk_get_core(void){ @@ -2074,7 +2076,7 @@ int main(int argc, char *argv[]){ const char *icon_name=LINPHONE_ICON_NAME; const char *app_name="Linphone"; LpConfig *factory; - char *chat_messages_db_file, *call_logs_db_file; + char *chat_messages_db_file, *call_logs_db_file, *friends_db_file; GError *error=NULL; const char *tmp; @@ -2212,9 +2214,11 @@ core_start: chat_messages_db_file=linphone_gtk_message_storage_get_db_file(NULL); call_logs_db_file = linphone_gtk_call_logs_storage_get_db_file(NULL); - linphone_gtk_init_liblinphone(config_file, factory_config_file, chat_messages_db_file, call_logs_db_file); + friends_db_file = linphone_gtk_friends_storage_get_db_file(NULL); + linphone_gtk_init_liblinphone(config_file, factory_config_file, chat_messages_db_file, call_logs_db_file, friends_db_file); g_free(chat_messages_db_file); g_free(call_logs_db_file); + g_free(friends_db_file); #ifdef CALL_LOGS_STORAGE_ENABLED linphone_gtk_call_log_update(the_ui); From 860ee180a8194fec545dfa099df4bd8d8a706e8f Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 17 Dec 2015 17:32:18 +0100 Subject: [PATCH 018/121] Tests done for friends' database storage --- coreapi/friend.c | 14 +++++-- coreapi/private.h | 2 +- tester/vcard_tester.c | 95 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 5 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index 823b7fce8..0d14b73b6 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -960,7 +960,7 @@ void linphone_core_friends_storage_init(LinphoneCore *lc) { linphone_core_friends_storage_close(lc); - ret=_linphone_sqlite3_open(lc->friends_db_file, &db); + ret = _linphone_sqlite3_open(lc->friends_db_file, &db); if (ret != SQLITE_OK) { errmsg = sqlite3_errmsg(db); ms_error("Error in the opening: %s.\n", errmsg); @@ -986,8 +986,13 @@ void linphone_core_friends_storage_close(LinphoneCore *lc) { static int create_friend(void *data, int argc, char **argv, char **colName) { MSList **list = (MSList **)data; LinphoneFriend *lf = NULL; + LinphoneVCard *vcard = NULL; + + vcard = linphone_vcard_new_from_vcard4_buffer(argv[1]); + lf = linphone_friend_new_from_vcard(vcard); //TODO - *list = ms_list_append(*list, lf); + *list = ms_list_append(*list, linphone_friend_ref(lf)); + linphone_friend_unref(lf); return 0; } @@ -1047,7 +1052,7 @@ void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf) { } } -const MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) { +MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) { char *buf; uint64_t begin,end; MSList *result = NULL; @@ -1079,7 +1084,7 @@ void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) { void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf) { } -const MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) { +MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) { return NULL; } @@ -1103,4 +1108,5 @@ void linphone_core_migrate_friends_from_rc_to_db(LinphoneCore *lc) { ms_warning("linphone has been compiled without sqlite, can't migrate friends"); return; #endif + //TODO } \ No newline at end of file diff --git a/coreapi/private.h b/coreapi/private.h index 009adb05b..22c83669d 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -399,7 +399,7 @@ void linphone_core_friends_storage_init(LinphoneCore *lc); void linphone_core_friends_storage_close(LinphoneCore *lc); void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf); void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf); -const MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc); +MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc); int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, socklen_t *socklen, int default_port); diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index a7294c1c4..669868d3e 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -72,9 +72,104 @@ static void linphone_vcard_import_a_lot_of_friends_test(void) { linphone_core_manager_destroy(manager); } +static void friends_if_no_db_set(void) { + LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneFriend *lf = linphone_friend_new(); + LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); + const MSList *friends = NULL; + + linphone_friend_set_address(lf, addr); + linphone_friend_set_name(lf, "Sylvain"); + linphone_core_add_friend(manager->lc, lf); + linphone_friend_unref(lf); + friends = linphone_core_get_friend_list(manager->lc); + BC_ASSERT_EQUAL(ms_list_size(friends), 1, int, "%d"); + + linphone_core_remove_friend(manager->lc, lf); + friends = linphone_core_get_friend_list(manager->lc); + BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); + + linphone_address_destroy(addr); + linphone_core_manager_destroy(manager); +} + +#ifdef FRIENDS_SQL_STORAGE_ENABLED +static void friends_migration(void) { + LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneFriend *lf = linphone_friend_new(); + LinphoneFriend *lf2 = NULL; + LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); + const MSList *friends = linphone_core_get_friend_list(manager->lc); + MSList *friends_from_db = NULL; + char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); + BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); + + linphone_friend_set_address(lf, addr); + linphone_friend_set_name(lf, "Sylvain"); + linphone_core_add_friend(manager->lc, lf); + linphone_friend_unref(lf); + friends = linphone_core_get_friend_list(manager->lc); + BC_ASSERT_EQUAL(ms_list_size(friends), 1, int, "%d"); + + unlink(friends_db); + linphone_core_set_friends_database_path(manager->lc, friends_db); + friends_from_db = linphone_core_fetch_friends_from_db(manager->lc); + BC_ASSERT_EQUAL_FATAL(ms_list_size(friends_from_db), 1, int, "%d"); + + lf2 = (LinphoneFriend *)friends_from_db->data; + BC_ASSERT_EQUAL(linphone_friend_get_name(lf2), linphone_friend_get_name(lf), const char *, "%s"); + + unlink(friends_db); + ms_free(friends_db); + linphone_address_destroy(addr); + friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); + linphone_core_manager_destroy(manager); +} + +static void friends_sqlite_storage(void) { + LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneFriend *lf = linphone_friend_new(); + LinphoneFriend *lf2 = NULL; + LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); + const MSList *friends = linphone_core_get_friend_list(manager->lc); + MSList *friends_from_db = NULL; + char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); + BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); + + unlink(friends_db); + linphone_core_set_friends_database_path(manager->lc, friends_db); + friends_from_db = linphone_core_fetch_friends_from_db(manager->lc); + BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); + + linphone_friend_set_address(lf, addr); + linphone_friend_set_name(lf, "Sylvain"); + linphone_core_add_friend(manager->lc, lf); + linphone_friend_unref(lf); + + friends = linphone_core_get_friend_list(manager->lc); + BC_ASSERT_EQUAL(ms_list_size(friends), 1, int, "%d"); + friends_from_db = linphone_core_fetch_friends_from_db(manager->lc); + BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d"); + + lf2 = (LinphoneFriend *)friends_from_db->data; + BC_ASSERT_EQUAL(linphone_friend_get_name(lf2), linphone_friend_get_name(lf), const char *, "%s"); + + unlink(friends_db); + ms_free(friends_db); + linphone_address_destroy(addr); + friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); + linphone_core_manager_destroy(manager); +} +#endif + test_t vcard_tests[] = { { "Import / Export friends from vCards", linphone_vcard_import_export_friends_test }, { "Import a lot of friends from vCards", linphone_vcard_import_a_lot_of_friends_test }, +#ifdef FRIENDS_SQL_STORAGE_ENABLED + { "Friends working if no db set", friends_if_no_db_set }, + { "Friends storage migration from rc to db", friends_migration }, + { "Friends storage in sqlite database", friends_sqlite_storage }, +#endif }; test_suite_t vcard_test_suite = { From 3eeb0974eae0c4f85219a6239066bbfa201bcc82 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 17 Dec 2015 17:42:46 +0100 Subject: [PATCH 019/121] Fixed compilation when belcard is not found --- coreapi/Makefile.am | 4 +++ coreapi/friend.c | 8 +++++ coreapi/vcard_stubs.c | 71 +++++++++++++++++++++++++++++++++++++++++++ tester/vcard_tester.c | 4 +++ 4 files changed, 87 insertions(+) create mode 100644 coreapi/vcard_stubs.c diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 6d9a1c179..6a918dd1e 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -114,8 +114,12 @@ else liblinphone_la_SOURCES+=linphone_tunnel_stubs.c linphone_tunnel.h endif +if BUILD_VCARD liblinphone_la_SOURCES+=vcard.cc vcard.h liblinphone_la_CXXFLAGS=-std=c++11 +else +liblinphone_la_SOURCES+=vcard_stubs.c vcard.h +endif liblinphone_la_LDFLAGS= -version-info $(LIBLINPHONE_SO_VERSION) -no-undefined diff --git a/coreapi/friend.c b/coreapi/friend.c index 0d14b73b6..77d6ca331 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -987,10 +987,18 @@ static int create_friend(void *data, int argc, char **argv, char **colName) { MSList **list = (MSList **)data; LinphoneFriend *lf = NULL; LinphoneVCard *vcard = NULL; + unsigned int storage_id = atoi(argv[0]); vcard = linphone_vcard_new_from_vcard4_buffer(argv[1]); lf = linphone_friend_new_from_vcard(vcard); + if (!lf) { + lf = linphone_friend_new(); + //TODO + } + //TODO + + lf->storage_id = storage_id; *list = ms_list_append(*list, linphone_friend_ref(lf)); linphone_friend_unref(lf); return 0; diff --git a/coreapi/vcard_stubs.c b/coreapi/vcard_stubs.c new file mode 100644 index 000000000..3bb7bed9e --- /dev/null +++ b/coreapi/vcard_stubs.c @@ -0,0 +1,71 @@ +/* +vcard_stubs.c +Copyright (C) 2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "vcard.h" + +struct _LinphoneVCard { +}; + +LinphoneVCard* linphone_vcard_new(void) { + return NULL; +} + +void linphone_vcard_free(LinphoneVCard *vCard) { + +} + +MSList* linphone_vcard_list_from_vcard4_file(const char *filename) { + return NULL; +} + +MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer) { + return NULL; +} + +LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer) { + return NULL; +} + +const char * linphone_vcard_as_vcard4_string(LinphoneVCard *vCard) { + return NULL; +} + +void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name) { + +} + +const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard) { + return NULL; +} + +void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char *sip_address) { + +} + +void linphone_vcard_remove_sip_address(LinphoneVCard *vCard, const char *sip_address) { + +} + +void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const char *sip_address) { + +} + +MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) { + return NULL; +} \ No newline at end of file diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 669868d3e..141c76c58 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -22,6 +22,7 @@ #include +#if BUILD_VCARD static char *create_filepath(const char *dir, const char *filename, const char *ext) { return ms_strdup_printf("%s/%s.%s", dir, filename, ext); } @@ -161,8 +162,10 @@ static void friends_sqlite_storage(void) { linphone_core_manager_destroy(manager); } #endif +#endif test_t vcard_tests[] = { +#if BUILD_VCARD { "Import / Export friends from vCards", linphone_vcard_import_export_friends_test }, { "Import a lot of friends from vCards", linphone_vcard_import_a_lot_of_friends_test }, #ifdef FRIENDS_SQL_STORAGE_ENABLED @@ -170,6 +173,7 @@ test_t vcard_tests[] = { { "Friends storage migration from rc to db", friends_migration }, { "Friends storage in sqlite database", friends_sqlite_storage }, #endif +#endif }; test_suite_t vcard_test_suite = { From 8ac8e1274a53897be6ea000eaf3b020dbc79fba9 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 17 Dec 2015 17:59:15 +0100 Subject: [PATCH 020/121] Fix vCard test suite no longer available since last commit --- configure.ac | 1 + tester/Makefile.am | 2 +- tester/vcard_tester.c | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 2bd3f8de8..8a142d0d3 100644 --- a/configure.ac +++ b/configure.ac @@ -896,6 +896,7 @@ if test x$enable_vcard != xfalse; then AC_LANG_C fi if test "$found_vcard" = "yes"; then + BELCARD_CFLAGS+=" -DVCARD_ENABLED" enable_vcard=true else if test x$enable_vcard = xtrue; then diff --git a/tester/Makefile.am b/tester/Makefile.am index 043ec3045..1d255acdf 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -153,7 +153,7 @@ dist_liblinphone_tester_DATA = tester_hosts messages.db AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/coreapi -I$(top_srcdir)/tester/common AM_CFLAGS = -DBC_CONFIG_FILE=\"config.h\" $(STRICT_OPTIONS) $(STRICT_OPTIONS_CC) \ -DIN_LINPHONE $(ORTP_CFLAGS) $(MEDIASTREAMER_CFLAGS) $(CUNIT_CFLAGS) \ - $(BELLESIP_CFLAGS) $(LIBXML2_CFLAGS) $(SQLITE3_CFLAGS) + $(BELLESIP_CFLAGS) $(LIBXML2_CFLAGS) $(SQLITE3_CFLAGS) $(BELCARD_CFLAGS) if BUILD_GTK_UI diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 141c76c58..ac2173b3e 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -22,7 +22,7 @@ #include -#if BUILD_VCARD +#ifdef VCARD_ENABLED static char *create_filepath(const char *dir, const char *filename, const char *ext) { return ms_strdup_printf("%s/%s.%s", dir, filename, ext); } @@ -165,7 +165,7 @@ static void friends_sqlite_storage(void) { #endif test_t vcard_tests[] = { -#if BUILD_VCARD +#ifdef VCARD_ENABLED { "Import / Export friends from vCards", linphone_vcard_import_export_friends_test }, { "Import a lot of friends from vCards", linphone_vcard_import_a_lot_of_friends_test }, #ifdef FRIENDS_SQL_STORAGE_ENABLED From 0b7a1deccf83a9a104f151fc625cdd3fc8935335 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 18 Dec 2015 14:45:52 +0100 Subject: [PATCH 021/121] Added friend storage to database + improved tests + needed changes in gtk app + friends' migration from rc to db --- coreapi/friend.c | 119 ++++++++++++++++++++++++++++++-------- coreapi/linphonecore.c | 11 +--- gtk/friendlist.c | 4 +- gtk/main.c | 3 + tester/Makefile.am | 3 +- tester/rcfiles/friends_rc | 21 +++++++ tester/vcard_tester.c | 54 +++++++++++------ 7 files changed, 162 insertions(+), 53 deletions(-) create mode 100644 tester/rcfiles/friends_rc diff --git a/coreapi/friend.c b/coreapi/friend.c index 77d6ca331..1c5a55e61 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -351,9 +351,13 @@ const LinphoneAddress *linphone_friend_get_address(const LinphoneFriend *lf){ } const char * linphone_friend_get_name(const LinphoneFriend *lf) { - LinphoneAddress *fr = lf->uri; - if (fr == NULL) return NULL; - return linphone_address_get_display_name(fr); + if (lf && lf->vcard) { + return linphone_vcard_get_full_name(lf->vcard); + } else if (lf && lf->uri) { + LinphoneAddress *fr = lf->uri; + return linphone_address_get_display_name(fr); + } + return NULL; } bool_t linphone_friend_get_send_subscribe(const LinphoneFriend *lf){ @@ -519,15 +523,15 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc) { if (fr->lc) { linphone_friend_update_subscribes(fr, NULL, linphone_core_should_subscribe_friends_only_when_registered(fr->lc)); } - ms_message("linphone_friend_apply() done."); + ms_debug("linphone_friend_apply() done."); lc->bl_refresh = TRUE; fr->commit = FALSE; } -void linphone_friend_edit(LinphoneFriend *fr){ +void linphone_friend_edit(LinphoneFriend *fr) { } -void linphone_friend_done(LinphoneFriend *fr){ +void linphone_friend_done(LinphoneFriend *fr) { ms_return_if_fail(fr); if (!fr->lc) return; linphone_friend_apply(fr, fr->lc); @@ -542,8 +546,7 @@ LinphoneFriend * linphone_core_create_friend_with_address(LinphoneCore *lc, cons return linphone_friend_new_with_address(address); } -void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) { - ms_return_if_fail(!lf->lc); +void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) { if (!lf->uri) { return; // Do not abort if friend doesn't have a SIP URI } @@ -578,13 +581,13 @@ void linphone_core_import_friend(LinphoneCore *lc, LinphoneFriend *lf) { void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* lf){ MSList *el = ms_list_find(lc->friends, lf); if (el != NULL) { - linphone_friend_unref((LinphoneFriend*)el->data); - lc->friends=ms_list_remove_link(lc->friends, el); + lc->friends = ms_list_remove_link(lc->friends, el); #ifdef FRIENDS_SQL_STORAGE_ENABLED linphone_core_remove_friend_from_db(lc, lf); #else linphone_core_write_friends_config(lc); #endif + linphone_friend_unref(lf); } else { ms_error("linphone_core_remove_friend(): friend [%p] is not part of core's list.", lf); } @@ -940,8 +943,13 @@ static void linphone_create_table(sqlite3* db) { char* errmsg = NULL; int ret; ret = sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS friends (" - - ");",//TODO + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "sip_uri TEXT NOT NULL," + "subscribe_policy INTEGER," + "send_subscribe INTEGER," + "ref_key TEXT," + "vCard TEXT" + ");", 0, 0, &errmsg); if (ret != SQLITE_OK) { ms_error("Error in creation: %s.\n", errmsg); @@ -957,6 +965,7 @@ void linphone_core_friends_storage_init(LinphoneCore *lc) { int ret; const char *errmsg; sqlite3 *db; + const MSList *friends = NULL; linphone_core_friends_storage_close(lc); @@ -971,6 +980,15 @@ void linphone_core_friends_storage_init(LinphoneCore *lc) { linphone_create_table(db); linphone_update_table(db); lc->friends_db = db; + + friends = linphone_core_fetch_friends_from_db(lc); + while (friends && friends->data) { + LinphoneFriend *lf = friends->data; + linphone_core_add_friend(lc, lf); + linphone_friend_unref(lf); + + friends = ms_list_next(friends); + } } void linphone_core_friends_storage_close(LinphoneCore *lc) { @@ -982,6 +1000,11 @@ void linphone_core_friends_storage_close(LinphoneCore *lc) { /* DB layout: * | 0 | storage_id + * | 1 | sip_uri + * | 2 | subscribe_policy + * | 3 | send_subscribe + * | 4 | ref_key + * | 5 | vCard */ static int create_friend(void *data, int argc, char **argv, char **colName) { MSList **list = (MSList **)data; @@ -989,16 +1012,18 @@ static int create_friend(void *data, int argc, char **argv, char **colName) { LinphoneVCard *vcard = NULL; unsigned int storage_id = atoi(argv[0]); - vcard = linphone_vcard_new_from_vcard4_buffer(argv[1]); + vcard = linphone_vcard_new_from_vcard4_buffer(argv[5]); lf = linphone_friend_new_from_vcard(vcard); if (!lf) { + LinphoneAddress *addr = linphone_address_new(argv[1]); lf = linphone_friend_new(); - //TODO + linphone_friend_set_address(lf, addr); } - - //TODO - + linphone_friend_set_inc_subscribe_policy(lf, atoi(argv[2])); + linphone_friend_send_subscribe(lf, atoi(argv[3])); + linphone_friend_set_ref_key(lf, argv[4]); lf->storage_id = storage_id; + *list = ms_list_append(*list, linphone_friend_ref(lf)); linphone_friend_unref(lf); return 0; @@ -1031,11 +1056,22 @@ void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) { char *buf; if (lf->storage_id > 0) { - buf = sqlite3_mprintf("UPDATE friends SET WHERE (id = %i);", //TODO + buf = sqlite3_mprintf("UPDATE friends SET sip_uri=%Q,subscribe_policy=%i,send_subscribe=%i,ref_key=%Q,vCard=%Q WHERE (id = %i);", + linphone_address_as_string(linphone_friend_get_address(lf)), + lf->pol, + lf->subscribe, + lf->refkey, + linphone_vcard_as_vcard4_string(linphone_friend_get_vcard(lf)), lf->storage_id ); } else { - buf = sqlite3_mprintf("INSERT INTO friends VALUES(NULL);"); //TODO + buf = sqlite3_mprintf("INSERT INTO friends VALUES(NULL,%Q,%i,%i,%Q,%Q);", + linphone_address_as_string(linphone_friend_get_address(lf)), + lf->pol, + lf->subscribe, + lf->refkey, + linphone_vcard_as_vcard4_string(linphone_friend_get_vcard(lf)) + ); } linphone_sql_request_generic(lc->friends_db, buf); sqlite3_free(buf); @@ -1047,12 +1083,14 @@ void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) { } void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf) { - if (lc && lc->friends_db && lf->storage_id > 0) { + if (lc && lc->friends_db) { char *buf; + if (lf->storage_id == 0) { + ms_error("Friend doesn't have a storage_id !"); + return; + } - buf = sqlite3_mprintf("DELETE FROM friends WHERE (id = %i);", - lf->storage_id - ); + buf = sqlite3_mprintf("DELETE FROM friends WHERE id = %i", lf->storage_id); linphone_sql_request_generic(lc->friends_db, buf); sqlite3_free(buf); @@ -1065,7 +1103,10 @@ MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) { uint64_t begin,end; MSList *result = NULL; - if (!lc || lc->friends_db == NULL) return NULL; + if (!lc || lc->friends_db == NULL) { + ms_warning("Either lc is NULL or friends database wasn't initialized with linphone_core_friends_storage_init() yet"); + return NULL; + } buf = sqlite3_mprintf("SELECT * FROM friends ORDER BY id"); @@ -1112,9 +1153,37 @@ void linphone_core_set_friends_database_path(LinphoneCore *lc, const char *path) } void linphone_core_migrate_friends_from_rc_to_db(LinphoneCore *lc) { + LpConfig *lpc = NULL; + LinphoneFriend *lf = NULL; + int i; #ifndef FRIENDS_SQL_STORAGE_ENABLED ms_warning("linphone has been compiled without sqlite, can't migrate friends"); return; #endif - //TODO + if (!lc) { + return; + } + + lpc = linphone_core_get_config(lc); + if (!lpc) { + ms_warning("this core has been started without a rc file, nothing to migrate"); + return; + } + if (lp_config_get_int(lpc, "misc", "friends_migration_done", 0) == 1) { + ms_warning("the friends migration has already been done, skipping..."); + return; + } + + for (i = 0; (lf = linphone_friend_new_from_config_file(lc, i)) != NULL; i++) { + char friend_section[32]; + + linphone_core_add_friend(lc, lf); + linphone_friend_unref(lf); + + snprintf(friend_section, sizeof(friend_section), "friend_%i", i); + lp_config_clean_section(lpc, friend_section); + } + + ms_debug("friends migration successful: %i friends migrated", i); + lp_config_set_int(lpc, "misc", "friends_migration_done", 1); } \ No newline at end of file diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 633c5c41f..3aba44e1a 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1364,19 +1364,14 @@ static void video_config_read(LinphoneCore *lc){ static void ui_config_read(LinphoneCore *lc) { +#ifndef FRIENDS_SQL_STORAGE_ENABLED LinphoneFriend *lf = NULL; -#ifdef FRIENDS_SQL_STORAGE_ENABLED - const MSList *friends = linphone_core_fetch_friends_from_db(lc); - while (friends && friends->data) { - lf = friends->data; - friends = ms_list_next(friends); -#else int i; - for (i=0;(lf=linphone_friend_new_from_config_file(lc,i))!=NULL;i++){ -#endif + for (i = 0; (lf = linphone_friend_new_from_config_file(lc, i)) != NULL; i++) { linphone_core_add_friend(lc, lf); linphone_friend_unref(lf); } +#endif call_logs_read_from_config_file(lc); } diff --git a/gtk/friendlist.c b/gtk/friendlist.c index 998a0d379..a2a6ca842 100644 --- a/gtk/friendlist.c +++ b/gtk/friendlist.c @@ -687,14 +687,14 @@ void linphone_gtk_show_friends(void){ LinphoneFriend *lf=(LinphoneFriend*)itf->data; const LinphoneAddress *f_uri=linphone_friend_get_address(lf); char *uri=linphone_address_as_string(f_uri); - const char *name=linphone_address_get_display_name(f_uri); + const char *name=linphone_friend_get_name(lf); const char *display=name; char *escaped=NULL; int nbmsg=0; //BuddyInfo *bi; gboolean send_subscribe=linphone_friend_get_send_subscribe(lf); - if (name==NULL || name[0]=='\0') { + if (display==NULL || display[0]=='\0') { display=linphone_address_get_username(f_uri); } gtk_list_store_append(store,&iter); diff --git a/gtk/main.c b/gtk/main.c index fb227f92e..411e3b998 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -2223,6 +2223,9 @@ core_start: #ifdef CALL_LOGS_STORAGE_ENABLED linphone_gtk_call_log_update(the_ui); #endif +#ifdef FRIENDS_SQL_STORAGE_ENABLED + linphone_gtk_show_friends(); +#endif /* do not lower timeouts under 30 ms because it exhibits a bug on gtk+/win32, with cpu running 20% all the time...*/ gtk_timeout_add(30,(GtkFunction)linphone_gtk_iterate,(gpointer)linphone_gtk_get_core()); diff --git a/tester/Makefile.am b/tester/Makefile.am index 1d255acdf..d2da519a5 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -68,7 +68,8 @@ RCFILES = \ rcfiles/remote_zero_length_params_rc\ rcfiles/stun_rc\ rcfiles/upnp_rc\ - rcfiles/zero_length_params_rc + rcfiles/zero_length_params_rc\ + rcfiles/friends_rc IMAGE_FILES = images/nowebcamCIF.jpg diff --git a/tester/rcfiles/friends_rc b/tester/rcfiles/friends_rc new file mode 100644 index 000000000..0582c4d95 --- /dev/null +++ b/tester/rcfiles/friends_rc @@ -0,0 +1,21 @@ +[net] +mtu=1300 + +[sip] +ping_with_options=0 +sip_random_port=1 + +[friend_0] +url=sip:sylvain@sip.linphone.org +pol=wait +subscribe=0 + +[friend_1] +url="François Grisez" +pol=accept +subscribe=1 + +[friend_2] +url=sip:margaux.clerc@sip.linphone.org +pol=deny +subscribe=0 diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index ac2173b3e..69d2d1415 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -42,7 +42,7 @@ static void linphone_vcard_import_export_friends_test(void) { linphone_core_export_friends_as_vcard4_file(manager->lc, export_filepath); - manager->lc->friends = ms_list_free(manager->lc->friends); + manager->lc->friends = ms_list_free_with_data(manager->lc->friends, (void (*)(void *))linphone_friend_unref); friends = linphone_core_get_friend_list(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); @@ -96,30 +96,24 @@ static void friends_if_no_db_set(void) { #ifdef FRIENDS_SQL_STORAGE_ENABLED static void friends_migration(void) { - LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); - LinphoneFriend *lf = linphone_friend_new(); - LinphoneFriend *lf2 = NULL; + LinphoneCoreManager* manager = linphone_core_manager_new2("friends_rc", FALSE); LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); const MSList *friends = linphone_core_get_friend_list(manager->lc); MSList *friends_from_db = NULL; char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); - linphone_friend_set_address(lf, addr); - linphone_friend_set_name(lf, "Sylvain"); - linphone_core_add_friend(manager->lc, lf); - linphone_friend_unref(lf); - friends = linphone_core_get_friend_list(manager->lc); - BC_ASSERT_EQUAL(ms_list_size(friends), 1, int, "%d"); - unlink(friends_db); linphone_core_set_friends_database_path(manager->lc, friends_db); friends_from_db = linphone_core_fetch_friends_from_db(manager->lc); - BC_ASSERT_EQUAL_FATAL(ms_list_size(friends_from_db), 1, int, "%d"); - - lf2 = (LinphoneFriend *)friends_from_db->data; - BC_ASSERT_EQUAL(linphone_friend_get_name(lf2), linphone_friend_get_name(lf), const char *, "%s"); + BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 3, int, "%d"); + if (ms_list_size(friends_from_db) < 3) { + goto end; + } + friends = linphone_core_get_friend_list(manager->lc); + BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d"); +end: unlink(friends_db); ms_free(friends_db); linphone_address_destroy(addr); @@ -146,15 +140,41 @@ static void friends_sqlite_storage(void) { linphone_friend_set_name(lf, "Sylvain"); linphone_core_add_friend(manager->lc, lf); linphone_friend_unref(lf); + BC_ASSERT_EQUAL(lf->storage_id, 1, int, "%d"); friends = linphone_core_get_friend_list(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends), 1, int, "%d"); + friends_from_db = linphone_core_fetch_friends_from_db(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d"); - + if (ms_list_size(friends_from_db) < 1) { + goto end; + } lf2 = (LinphoneFriend *)friends_from_db->data; - BC_ASSERT_EQUAL(linphone_friend_get_name(lf2), linphone_friend_get_name(lf), const char *, "%s"); + BC_ASSERT_STRING_EQUAL(linphone_friend_get_name(lf2), linphone_friend_get_name(lf)); + BC_ASSERT_EQUAL(lf2->storage_id, lf->storage_id, int, "%i"); + BC_ASSERT_STRING_EQUAL(linphone_address_as_string(linphone_friend_get_address(lf2)), linphone_address_as_string(linphone_friend_get_address(lf))); + + linphone_friend_edit(lf); + linphone_friend_set_name(lf, "Margaux"); + linphone_friend_done(lf); + friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); + friends_from_db = linphone_core_fetch_friends_from_db(manager->lc); + BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d"); + if (ms_list_size(friends_from_db) < 1) { + goto end; + } + lf2 = (LinphoneFriend *)friends_from_db->data; + BC_ASSERT_STRING_EQUAL(linphone_friend_get_name(lf2), "Margaux"); + friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); + linphone_core_remove_friend(manager->lc, lf); + friends = linphone_core_get_friend_list(manager->lc); + BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); + friends_from_db = linphone_core_fetch_friends_from_db(manager->lc); + BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 0, int, "%d"); + +end: unlink(friends_db); ms_free(friends_db); linphone_address_destroy(addr); From 9001f40f1a0f80607eea9523005f6df8ca3bb64c Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 21 Dec 2015 14:45:59 +0100 Subject: [PATCH 022/121] Updated CMake files for belcard and belr --- CMakeLists.txt | 11 +++++++++ cmake/FindBelcard.cmake | 55 +++++++++++++++++++++++++++++++++++++++++ coreapi/CMakeLists.txt | 8 ++++++ tester/CMakeLists.txt | 1 + 4 files changed, 75 insertions(+) create mode 100644 cmake/FindBelcard.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index f4f45d39b..53186c8d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,8 @@ cmake_dependent_option(ENABLE_ASSISTANT "Turn on assistant compiling." YES "ENAB option(ENABLE_DEBUG_LOGS "Turn on or off debug level logs." NO) option(ENABLE_NLS "Build with internationalisation support" YES) option(ENABLE_CALL_LOGS_STORAGE "Turn on compilation of call logs storage." YES) +option(ENABLE_FRIENDS_SQL_STORAGE "Turn on compilation of friends sql storage." YES) +option(ENABLE_VCARD "Turn on compilation of vcard4 support." YES) macro(apply_compile_flags SOURCE_FILES) @@ -163,9 +165,15 @@ endif() if(ENABLE_CALL_LOGS_STORAGE) find_package(Sqlite3 REQUIRED) endif() +if (ENABLE_FRIENDS_SQL_STORAGE) + find_package(Sqlite3 REQUIRED) +endif() if(ENABLE_LIME) set(HAVE_LIME 1) endif() +if (ENABLE_VCARD) + find_package(Belcard REQUIRED) +endif() if(UNIX AND NOT APPLE) include(CheckIncludeFiles) @@ -200,6 +208,9 @@ if(SQLITE3_FOUND) if(ENABLE_CALL_LOGS_STORAGE) add_definitions("-DCALL_LOGS_STORAGE_ENABLED") endif() + if(ENABLE_FRIENDS_SQL_STORAGE) + add_definitions("-DFRIENDS_SQL_STORAGE_ENABLED") + endif() endif() if(INTL_FOUND) set(HAVE_INTL 1) diff --git a/cmake/FindBelcard.cmake b/cmake/FindBelcard.cmake new file mode 100644 index 000000000..810ed0d4e --- /dev/null +++ b/cmake/FindBelcard.cmake @@ -0,0 +1,55 @@ +############################################################################ +# FindBelcard.cmake +# Copyright (C) 2015 Belledonne Communications, Grenoble France +# +############################################################################ +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +############################################################################ +# +# - Find the belcard include file and library +# +# BELCARD_FOUND - system has belcard +# BELCARD_INCLUDE_DIRS - the belcard include directory +# BELCARD_LIBRARIES - The libraries needed to use belcard + +set(_BELCARD_ROOT_PATHS + ${CMAKE_INSTALL_PREFIX} +) + +find_path(BELCARD_INCLUDE_DIRS + NAMES belcard.hpp + HINTS _BELCARD_ROOT_PATHS + PATH_SUFFIXES include +) + +if(BELCARD_INCLUDE_DIRS) + set(HAVE_BELCARD_H 1) +endif() + +find_library(BELCARD_LIBRARIES + NAMES belr belcard + HINTS ${_BELCARD_ROOT_PATHS} + PATH_SUFFIXES bin lib +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Belcard + DEFAULT_MSG + BELCARD_INCLUDE_DIRS BELCARD_LIBRARIES HAVE_BELCARD_H +) + +mark_as_advanced(BELCARD_INCLUDE_DIRS BELCARD_LIBRARIES HAVE_BELCARD_H) diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index 2d911d0ed..989051e89 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -49,6 +49,7 @@ set(LINPHONE_HEADER_FILES sipsetup.h xml2lpc.h xmlrpc.h + vcard.h ) set(LINPHONE_SOURCE_FILES_C @@ -165,6 +166,13 @@ endif() if(INTL_FOUND) list(APPEND LIBS ${INTL_LIBRARIES}) endif() +if(BELCARD_FOUND) + list(APPEND LIBS ${BELCARD_LIBRARIES}) + list(APPEND LINPHONE_SOURCE_FILES_CXX vcard.cc) + add_definitions(-DVCARD_ENABLED) +else() + list(APPEND LINPHONE_SOURCE_FILES_C vcard_stubs.c) +endif() if(ENABLE_STATIC) add_library(linphone STATIC ${LINPHONE_HEADER_FILES} ${LINPHONE_SOURCE_FILES_C} ${LINPHONE_SOURCE_FILES_CXX}) diff --git a/tester/CMakeLists.txt b/tester/CMakeLists.txt index 7ed25ecaa..5309cf44f 100644 --- a/tester/CMakeLists.txt +++ b/tester/CMakeLists.txt @@ -46,6 +46,7 @@ set(SOURCE_FILES tunnel_tester.c upnp_tester.c video_tester.c + vcard_tester.c ) apply_compile_flags(SOURCE_FILES "CPP" "C") From 0d9eed4ef1c509e0518ffe3154791a1b36899bea Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 21 Dec 2015 17:20:09 +0100 Subject: [PATCH 023/121] Fix segfault + uses new singleton to parse friends from database much faster --- coreapi/friend.c | 9 +++++---- coreapi/vcard.cc | 15 ++++++--------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index ba6d27ced..ac2ad9970 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -858,13 +858,14 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * LinphoneVCard *vcard = (LinphoneVCard *)vcards->data; LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); if (lf) { - linphone_friend_list_import_friend(lc->friendlist, lf); - lf->lc = lc; + if (LinphoneFriendListOK == linphone_friend_list_import_friend(lc->friendlist, lf)) { + lf->lc = lc; #ifdef FRIENDS_SQL_STORAGE_ENABLED - linphone_core_store_friend_in_db(lc, lf); + linphone_core_store_friend_in_db(lc, lf); #endif + count++; + } linphone_friend_unref(lf); - count++; } vcards = ms_list_next(vcards); } diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index c50043e03..0ecff260c 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -41,8 +41,8 @@ extern "C" void linphone_vcard_free(LinphoneVCard *vCard) { extern "C" MSList* linphone_vcard_list_from_vcard4_file(const char *filename) { MSList *result = NULL; if (filename && ortp_file_exist(filename) == 0) { - belcard::BelCardParser *parser = new belcard::BelCardParser(); - shared_ptr belCards = parser->parseFile(filename); + belcard::BelCardParser parser = belcard::BelCardParser::getInstance(); + shared_ptr belCards = parser.parseFile(filename); if (belCards) { for (auto it = belCards->getCards().begin(); it != belCards->getCards().end(); ++it) { shared_ptr belcard = (*it); @@ -51,7 +51,6 @@ extern "C" MSList* linphone_vcard_list_from_vcard4_file(const char *filename) { result = ms_list_append(result, vCard); } } - delete parser; } return result; } @@ -59,8 +58,8 @@ extern "C" MSList* linphone_vcard_list_from_vcard4_file(const char *filename) { extern "C" MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer) { MSList *result = NULL; if (buffer) { - belcard::BelCardParser *parser = new belcard::BelCardParser(); - shared_ptr belCards = parser->parse(buffer); + belcard::BelCardParser parser = belcard::BelCardParser::getInstance(); + shared_ptr belCards = parser.parse(buffer); if (belCards) { for (auto it = belCards->getCards().begin(); it != belCards->getCards().end(); ++it) { shared_ptr belCard = (*it); @@ -69,7 +68,6 @@ extern "C" MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer) { result = ms_list_append(result, vCard); } } - delete parser; } return result; } @@ -77,13 +75,12 @@ extern "C" MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer) { extern "C" LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer) { LinphoneVCard *vCard = NULL; if (buffer) { - belcard::BelCardParser *parser = new belcard::BelCardParser(); - shared_ptr belCard = parser->parseOne(buffer); + belcard::BelCardParser parser = belcard::BelCardParser::getInstance(); + shared_ptr belCard = parser.parseOne(buffer); if (belCard) { vCard = linphone_vcard_new(); vCard->belCard = belCard; } - delete parser; } return vCard; } From f291f53e43bb74db29bbc1487b6e73e0ec61d8e3 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 21 Dec 2015 17:25:09 +0100 Subject: [PATCH 024/121] When importing friend from vcard, disable presence because currently it takes too much time when dealing with hundreds of vcards/friends --- coreapi/friend.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/coreapi/friend.c b/coreapi/friend.c index ac2ad9970..4ed650f25 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -835,6 +835,9 @@ LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard) { sipAddresses = linphone_vcard_get_sip_addresses(vcard); fr = linphone_friend_new(); + fr->pol = LinphoneSPDeny; + fr->subscribe = FALSE; + linphone_friend_set_vcard(fr, vcard); if (sipAddresses) { From 06b099d13763234d19c0e4d07bfc8ef4a1efafb8 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 21 Dec 2015 17:30:33 +0100 Subject: [PATCH 025/121] Added a comment to explain why presence is disabled when importing friends from vcards --- coreapi/friend.c | 1 + 1 file changed, 1 insertion(+) diff --git a/coreapi/friend.c b/coreapi/friend.c index 4ed650f25..852d14a25 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -835,6 +835,7 @@ LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard) { sipAddresses = linphone_vcard_get_sip_addresses(vcard); fr = linphone_friend_new(); + // Currently presence takes too much time when dealing with hundreds of friends, so I disabled it for now fr->pol = LinphoneSPDeny; fr->subscribe = FALSE; From 7f6c61f3590beaaf905153322fbb2fc1f63d9a59 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 22 Dec 2015 11:13:06 +0100 Subject: [PATCH 026/121] Updated CMakefile for vCard & belcard --- CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 53186c8d8..eb30a1e26 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -172,7 +172,11 @@ if(ENABLE_LIME) set(HAVE_LIME 1) endif() if (ENABLE_VCARD) - find_package(Belcard REQUIRED) + find_package(Belcard) + if(NOT BELCARD_FOUND) + message(WARNING "Could not find the belcard library!") + set(ENABLE_VCARD OFF CACHE BOOL "Enable vcard support." FORCE) + endif() endif() if(UNIX AND NOT APPLE) @@ -193,6 +197,9 @@ include_directories( if(ENABLE_TUNNEL) include_directories(${TUNNEL_INCLUDE_DIRS}) endif() +if (ENABLE_VCARD) + include_directories(${BELCARD_INCLUDE_DIRS}) +endif() include_directories(${XML2_INCLUDE_DIRS}) From ce349693f90e1d9331b88ebec244eb33888791c6 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 22 Dec 2015 16:30:18 +0100 Subject: [PATCH 027/121] Updated oRTP --- oRTP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oRTP b/oRTP index 4a4ecae9e..d9df9695a 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 4a4ecae9eebdc967bbfb03360ad787e52d6ad267 +Subproject commit d9df9695a2fdb788e66d838cc5a94fa2b76ae532 From 378cd8fb192c6a5b8b4491808e857f49a5a45615 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 22 Dec 2015 16:54:58 +0100 Subject: [PATCH 028/121] Forgot add definition + error log when trying to import/export friends using vcards if not supported --- CMakeLists.txt | 2 ++ coreapi/friend.c | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eb30a1e26..4b744c01f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,6 +176,8 @@ if (ENABLE_VCARD) if(NOT BELCARD_FOUND) message(WARNING "Could not find the belcard library!") set(ENABLE_VCARD OFF CACHE BOOL "Enable vcard support." FORCE) + else() + add_definitions("-DVCARD_ENABLED") endif() endif() diff --git a/coreapi/friend.c b/coreapi/friend.c index 852d14a25..b937c7ddb 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -858,6 +858,9 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * MSList *vcards = linphone_vcard_list_from_vcard4_file(vcard_file); int count = 0; +#ifndef VCARD_ENABLED + ms_error("vCard support wasn't enabled at compilation time"); +#else while (vcards != NULL && vcards->data != NULL) { LinphoneVCard *vcard = (LinphoneVCard *)vcards->data; LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); @@ -876,7 +879,7 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * #ifndef FRIENDS_SQL_STORAGE_ENABLED linphone_core_write_friends_config(lc); #endif - +#endif return count; } @@ -890,6 +893,9 @@ void linphone_core_export_friends_as_vcard4_file(LinphoneCore *lc, const char *v return; } +#ifndef VCARD_ENABLED + ms_error("vCard support wasn't enabled at compilation time"); +#else while (friends != NULL && friends->data != NULL) { LinphoneFriend *lf = (LinphoneFriend *)friends->data; LinphoneVCard *vcard = linphone_friend_get_vcard(lf); @@ -901,6 +907,7 @@ void linphone_core_export_friends_as_vcard4_file(LinphoneCore *lc, const char *v } friends = ms_list_next(friends); } +#endif fclose(file); } From f684e15247f9586e80e522b9aef123b47c1d2c9b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 22 Dec 2015 16:57:47 +0100 Subject: [PATCH 029/121] Fix unused variables error --- coreapi/friend.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index b937c7ddb..96ef99975 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -860,7 +860,7 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * #ifndef VCARD_ENABLED ms_error("vCard support wasn't enabled at compilation time"); -#else +#endif while (vcards != NULL && vcards->data != NULL) { LinphoneVCard *vcard = (LinphoneVCard *)vcards->data; LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); @@ -878,7 +878,6 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * } #ifndef FRIENDS_SQL_STORAGE_ENABLED linphone_core_write_friends_config(lc); -#endif #endif return count; } @@ -895,7 +894,7 @@ void linphone_core_export_friends_as_vcard4_file(LinphoneCore *lc, const char *v #ifndef VCARD_ENABLED ms_error("vCard support wasn't enabled at compilation time"); -#else +#endif while (friends != NULL && friends->data != NULL) { LinphoneFriend *lf = (LinphoneFriend *)friends->data; LinphoneVCard *vcard = linphone_friend_get_vcard(lf); @@ -907,7 +906,6 @@ void linphone_core_export_friends_as_vcard4_file(LinphoneCore *lc, const char *v } friends = ms_list_next(friends); } -#endif fclose(file); } From 29715bd4eed5cfbd2804fa97b6ac4ed71cb83769 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 22 Dec 2015 17:13:01 +0100 Subject: [PATCH 030/121] Removed duplicated definition for VCARD_ENABLED + fixed FindBelcard --- CMakeLists.txt | 2 -- cmake/FindBelcard.cmake | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b744c01f..eb30a1e26 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,8 +176,6 @@ if (ENABLE_VCARD) if(NOT BELCARD_FOUND) message(WARNING "Could not find the belcard library!") set(ENABLE_VCARD OFF CACHE BOOL "Enable vcard support." FORCE) - else() - add_definitions("-DVCARD_ENABLED") endif() endif() diff --git a/cmake/FindBelcard.cmake b/cmake/FindBelcard.cmake index 810ed0d4e..bab59c2c1 100644 --- a/cmake/FindBelcard.cmake +++ b/cmake/FindBelcard.cmake @@ -33,7 +33,7 @@ set(_BELCARD_ROOT_PATHS find_path(BELCARD_INCLUDE_DIRS NAMES belcard.hpp HINTS _BELCARD_ROOT_PATHS - PATH_SUFFIXES include + PATH_SUFFIXES include/belcard ) if(BELCARD_INCLUDE_DIRS) From 3695a15374f422ebe531773a5a9ed64b941bda5e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 22 Dec 2015 17:24:39 +0100 Subject: [PATCH 031/121] Fix cmake compilation of vcard.cc --- CMakeLists.txt | 2 ++ coreapi/CMakeLists.txt | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eb30a1e26..de89c2d4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -234,8 +234,10 @@ endif() set(STRICT_OPTIONS_CPP ) set(STRICT_OPTIONS_C ) +set(STRICT_OPTIONS_CXX ) set(STRICT_OPTIONS_OBJC ) if(NOT MSVC) + list(APPEND STRICT_OPTIONS_CXX "-std=c++11") list(APPEND STRICT_OPTIONS_CPP "-Wall" "-Wuninitialized" "-Wno-error=deprecated-declarations") list(APPEND STRICT_OPTIONS_C "-Wdeclaration-after-statement" "-Wstrict-prototypes" "-Wno-error=strict-prototypes") if(CMAKE_C_COMPILER_ID STREQUAL "Clang") diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index 989051e89..6ac661726 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -137,9 +137,6 @@ add_definitions( -DLIBLINPHONE_EXPORTS ) -apply_compile_flags(LINPHONE_SOURCE_FILES_C "CPP" "C") -apply_compile_flags(LINPHONE_SOURCE_FILES_CXX "CPP" "CXX") - set(LIBS ${BELLESIP_LIBRARIES} ${MEDIASTREAMER2_LIBRARIES} @@ -174,6 +171,9 @@ else() list(APPEND LINPHONE_SOURCE_FILES_C vcard_stubs.c) endif() +apply_compile_flags(LINPHONE_SOURCE_FILES_C "CPP" "C") +apply_compile_flags(LINPHONE_SOURCE_FILES_CXX "CPP" "CXX") + if(ENABLE_STATIC) add_library(linphone STATIC ${LINPHONE_HEADER_FILES} ${LINPHONE_SOURCE_FILES_C} ${LINPHONE_SOURCE_FILES_CXX}) target_link_libraries(linphone ${LIBS}) From 97ed671abcc0e7e633daf0c2af31e87251a77c47 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 23 Dec 2015 11:06:17 +0100 Subject: [PATCH 032/121] Updated cmake files for belcard --- CMakeLists.txt | 6 +++++- cmake/FindBelcard.cmake | 2 +- cmake/LinphoneConfig.cmake.in | 11 +++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index de89c2d4b..5316eb316 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -172,7 +172,11 @@ if(ENABLE_LIME) set(HAVE_LIME 1) endif() if (ENABLE_VCARD) - find_package(Belcard) + if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) + include("${EP_belcard_CONFIG_DIR}/BelcardConfig.cmake") + else() + find_package(Belcard) + endif() if(NOT BELCARD_FOUND) message(WARNING "Could not find the belcard library!") set(ENABLE_VCARD OFF CACHE BOOL "Enable vcard support." FORCE) diff --git a/cmake/FindBelcard.cmake b/cmake/FindBelcard.cmake index bab59c2c1..4a50a3f2e 100644 --- a/cmake/FindBelcard.cmake +++ b/cmake/FindBelcard.cmake @@ -41,7 +41,7 @@ if(BELCARD_INCLUDE_DIRS) endif() find_library(BELCARD_LIBRARIES - NAMES belr belcard + NAMES belcard HINTS ${_BELCARD_ROOT_PATHS} PATH_SUFFIXES bin lib ) diff --git a/cmake/LinphoneConfig.cmake.in b/cmake/LinphoneConfig.cmake.in index 9bcd9dfa4..9a349cc41 100644 --- a/cmake/LinphoneConfig.cmake.in +++ b/cmake/LinphoneConfig.cmake.in @@ -38,6 +38,13 @@ find_package(BelleSIP REQUIRED) if(@ENABLE_TUNNEL@) find_package(Tunnel) endif() +if(@ENABLE_VCARD@) + if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) + include("${EP_belcard_CONFIG_DIR}/BelcardConfig.cmake") + else() + find_package(Belcard) + endif() +endif() get_filename_component(LINPHONE_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) set(LINPHONE_INCLUDE_DIRS "${LINPHONE_CMAKE_DIR}/../../../include") @@ -51,4 +58,8 @@ if(TUNNEL_FOUND) list(APPEND LINPHONE_INCLUDE_DIRS ${TUNNEL_INCLUDE_DIRS}) list(APPEND LINPHONE_LIBRARIES ${TUNNEL_LIBRARIES}) endif() +if(BELCARD_FOUND) + list(APPEND LINPHONE_INCLUDE_DIRS ${BELCARD_INCLUDE_DIRS}) + list(APPEND LINPHONE_LIBRARIES ${BELCARD_LIBRARIES}) +endif() set(LINPHONE_FOUND 1) From 5f58df86e01674ca51dbfaf97f44dcf8e917e273 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 24 Dec 2015 10:08:48 +0100 Subject: [PATCH 033/121] Updated Android Makefile for belr and belcard + renamed friend variables to lf because friend is a keyword --- build/android/Android.mk | 20 +++++-- build/android/liblinphone_tester.mk | 1 + coreapi/friendlist.c | 90 ++++++++++++++--------------- coreapi/private.h | 2 +- 4 files changed, 63 insertions(+), 50 deletions(-) diff --git a/build/android/Android.mk b/build/android/Android.mk index b0d51fc32..a6aa17fe4 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -77,7 +77,7 @@ LOCAL_SRC_FILES := \ xml2lpc.c \ xml.c \ xmlrpc.c \ - vtables.c + vtables.c \ ifndef LIBLINPHONE_VERSION LIBLINPHONE_VERSION = "Devel" @@ -126,7 +126,7 @@ LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/../../../gen \ $(LOCAL_PATH)/../../externals/libxml2/include \ $(LOCAL_PATH)/../../externals/build/libxml2 \ - $(LOCAL_PATH)/../../externals/polarssl/include + $(LOCAL_PATH)/../../externals/polarssl/include \ LOCAL_LDLIBS += -llog -ldl -lz @@ -239,6 +239,10 @@ ifeq ($(BUILD_SRTP), 1) LOCAL_C_INCLUDES += $(SRTP_C_INCLUDE) endif +ifeq ($(BUILD_VCARD),1) + LOCAL_C_INCLUDES += $(VCARD_C_INCLUDE) +endif + ifeq ($(BUILD_ILBC), 1) ifneq ($(TARGET_ARCH_ABI),armeabi) LOCAL_CFLAGS += -DHAVE_ILBC=1 @@ -260,8 +264,16 @@ ifeq ($(BUILD_SRTP),1) LOCAL_STATIC_LIBRARIES += libsrtp endif +ifeq ($(BUILD_VCARD),1) + LOCAL_CFLAGS += -DVCARD_ENABLED + LOCAL_SRC_FILES += vcard.cc + LOCAL_STATIC_LIBRARIES += libbelr libbelcard +else + LOCAL_SRC_FILES += vcard_stubs.c +endif + ifeq ($(BUILD_SQLITE),1) -LOCAL_CFLAGS += -DMSG_STORAGE_ENABLED -DCALL_LOGS_STORAGE_ENABLED +LOCAL_CFLAGS += -DMSG_STORAGE_ENABLED -DCALL_LOGS_STORAGE_ENABLED -DFRIENDS_SQL_STORAGE_ENABLED LOCAL_STATIC_LIBRARIES += liblinsqlite LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/../../externals/sqlite3/ @@ -283,7 +295,7 @@ LOCAL_MODULE_FILENAME := liblinphone-$(TARGET_ARCH_ABI) include $(BUILD_SHARED_LIBRARY) -LOCAL_CPPFLAGS=$(LOCAL_CFLAGS) +LOCAL_CPPFLAGS += $(LOCAL_CFLAGS) LOCAL_CFLAGS += -Wdeclaration-after-statement LOCAL_LDFLAGS := -Wl,-soname,$(LOCAL_MODULE_FILENAME).so diff --git a/build/android/liblinphone_tester.mk b/build/android/liblinphone_tester.mk index 8395df144..042243da0 100644 --- a/build/android/liblinphone_tester.mk +++ b/build/android/liblinphone_tester.mk @@ -24,6 +24,7 @@ common_SRC_FILES := \ tunnel_tester.c \ upnp_tester.c \ multicast_call_tester.c \ + vcard_tester.c common_C_INCLUDES += \ $(LOCAL_PATH) \ diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index b9f8210ba..53aa2f499 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -56,8 +56,8 @@ static char * create_resource_list_xml(const LinphoneFriendList *list) { err = xmlTextWriterStartElement(writer, (const xmlChar *)"list"); } for (elem = list->friends; elem != NULL; elem = elem->next) { - LinphoneFriend *friend = (LinphoneFriend *)elem->data; - char *uri = linphone_address_as_string_uri_only(friend->uri); + LinphoneFriend *lf = (LinphoneFriend *)elem->data; + char *uri = linphone_address_as_string_uri_only(lf->uri); if (err >= 0) { err = xmlTextWriterStartElement(writer, (const xmlChar *)"entry"); } @@ -98,7 +98,7 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList xml_ctx->doc = xmlReadDoc((const unsigned char*)first_part_body, 0, NULL, 0); if (xml_ctx->doc != NULL) { char xpath_str[MAX_XPATH_LENGTH]; - LinphoneFriend *friend; + LinphoneFriend *lf; LinphoneContent *presence_part; xmlXPathObjectPtr resource_object; const char *version_str = NULL; @@ -132,8 +132,8 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList if ((strcmp(full_state_str, "true") == 0) || (strcmp(full_state_str, "1") == 0)) { MSList *l = list->friends; for (; l != NULL; l = l->next) { - friend = (LinphoneFriend *)l->data; - linphone_friend_set_presence_model(friend, NULL); + lf = (LinphoneFriend *)l->data; + linphone_friend_set_presence_model(lf, NULL); } full_state = TRUE; } @@ -150,8 +150,8 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList snprintf(xpath_str, sizeof(xpath_str), "/rlmi:list/rlmi:resource[%i]/@uri", i); uri = linphone_get_xml_text_content(xml_ctx, xpath_str); if (uri == NULL) continue; - friend = linphone_friend_list_find_friend_by_uri(list, uri); - if (friend != NULL) { + lf = linphone_friend_list_find_friend_by_uri(list, uri); + if (lf != NULL) { const char *state = NULL; snprintf(xpath_str, sizeof(xpath_str),"/rlmi:list/rlmi:resource[%i]/rlmi:instance/@state", i); state = linphone_get_xml_text_content(xml_ctx, xpath_str); @@ -167,10 +167,10 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList SalPresenceModel *presence = NULL; linphone_notify_parse_presence(linphone_content_get_type(presence_part), linphone_content_get_subtype(presence_part), linphone_content_get_string_buffer(presence_part), &presence); if (presence != NULL) { - friend->presence_received = TRUE; - linphone_friend_set_presence_model(friend, (LinphonePresenceModel *)presence); + lf->presence_received = TRUE; + linphone_friend_set_presence_model(lf, (LinphonePresenceModel *)presence); if (full_state == FALSE) { - linphone_core_notify_notify_presence_received(list->lc, friend); + linphone_core_notify_notify_presence_received(list->lc, lf); } } linphone_content_unref(presence_part); @@ -179,7 +179,7 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList if (cid != NULL) linphone_free_xml_text_content(cid); } if (state != NULL) linphone_free_xml_text_content(state); - friend->subscribe_active = TRUE; + lf->subscribe_active = TRUE; } linphone_free_xml_text_content(uri); } @@ -189,9 +189,9 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList if (full_state == TRUE) { MSList *l = list->friends; for (; l != NULL; l = l->next) { - friend = (LinphoneFriend *)l->data; - if (linphone_friend_is_presence_received(friend) == TRUE) { - linphone_core_notify_notify_presence_received(list->lc, friend); + lf = (LinphoneFriend *)l->data; + if (linphone_friend_is_presence_received(lf) == TRUE) { + linphone_core_notify_notify_presence_received(list->lc, lf); } } } @@ -207,8 +207,8 @@ static bool_t linphone_friend_list_has_subscribe_inactive(const LinphoneFriendLi MSList *l = list->friends; bool_t has_subscribe_inactive = FALSE; for (; l != NULL; l = l->next) { - LinphoneFriend *friend = (LinphoneFriend *)l->data; - if (friend->subscribe_active != TRUE) { + LinphoneFriend *lf = (LinphoneFriend *)l->data; + if (lf->subscribe_active != TRUE) { has_subscribe_inactive = TRUE; break; } @@ -290,32 +290,32 @@ void linphone_friend_list_set_rls_uri(LinphoneFriendList *list, const char *rls_ } } -LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *friend) { - if ((friend->lc != NULL) || (friend->uri == NULL)) return LinphoneFriendListInvalidFriend; - if (ms_list_find(list->friends, friend) != NULL) { +LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf) { + if ((lf->lc != NULL) || (lf->uri == NULL)) return LinphoneFriendListInvalidFriend; + if (ms_list_find(list->friends, lf) != NULL) { char *tmp = NULL; - const LinphoneAddress *addr = linphone_friend_get_address(friend); + const LinphoneAddress *addr = linphone_friend_get_address(lf); if (addr) tmp = linphone_address_as_string(addr); ms_warning("Friend %s already in list [%s], ignored.", tmp ? tmp : "unknown", list->display_name); if (tmp) ms_free(tmp); } else { - return linphone_friend_list_import_friend(list, friend); + return linphone_friend_list_import_friend(list, lf); } return LinphoneFriendListOK; } -LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *friend) { - if ((friend->lc != NULL) || (friend->uri == NULL)) return LinphoneFriendListInvalidFriend; - list->friends = ms_list_append(list->friends, linphone_friend_ref(friend)); +LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf) { + if ((lf->lc != NULL) || (lf->uri == NULL)) return LinphoneFriendListInvalidFriend; + list->friends = ms_list_append(list->friends, linphone_friend_ref(lf)); return LinphoneFriendListOK; } -LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *friend) { - MSList *elem = ms_list_find(list->friends, friend); +LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *lf) { + MSList *elem = ms_list_find(list->friends, lf); if (elem == NULL) return LinphoneFriendListNonExistentFriend; #ifdef FRIENDS_SQL_STORAGE_ENABLED - linphone_core_remove_friend_from_db(friend->lc, friend); + linphone_core_remove_friend_from_db(lf->lc, lf); #endif linphone_friend_unref((LinphoneFriend *)elem->data); @@ -324,29 +324,29 @@ LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList * } LinphoneFriend * linphone_friend_list_find_friend_by_address(const LinphoneFriendList *list, const LinphoneAddress *address) { - LinphoneFriend *friend = NULL; + LinphoneFriend *lf = NULL; const MSList *elem; for (elem = list->friends; elem != NULL; elem = elem->next) { - friend = (LinphoneFriend *)elem->data; - if (linphone_address_weak_equal(friend->uri, address)) - return friend; + lf = (LinphoneFriend *)elem->data; + if (linphone_address_weak_equal(lf->uri, address)) + return lf; } return NULL; } LinphoneFriend * linphone_friend_list_find_friend_by_uri(const LinphoneFriendList *list, const char *uri) { LinphoneAddress *address = linphone_address_new(uri); - LinphoneFriend *friend = address ? linphone_friend_list_find_friend_by_address(list, address) : NULL; + LinphoneFriend *lf = address ? linphone_friend_list_find_friend_by_address(list, address) : NULL; if (address) linphone_address_unref(address); - return friend; + return lf; } LinphoneFriend * linphone_friend_list_find_friend_by_ref_key(const LinphoneFriendList *list, const char *ref_key) { const MSList *elem; if (ref_key == NULL) return NULL; for (elem = list->friends; elem != NULL; elem = elem->next) { - LinphoneFriend *friend = (LinphoneFriend *)elem->data; - if ((friend->refkey != NULL) && (strcmp(friend->refkey, ref_key) == 0)) return friend; + LinphoneFriend *lf = (LinphoneFriend *)elem->data; + if ((lf->refkey != NULL) && (strcmp(lf->refkey, ref_key) == 0)) return lf; } return NULL; } @@ -354,8 +354,8 @@ LinphoneFriend * linphone_friend_list_find_friend_by_ref_key(const LinphoneFrien LinphoneFriend * linphone_friend_list_find_friend_by_inc_subscribe(const LinphoneFriendList *list, SalOp *op) { const MSList *elem; for (elem = list->friends; elem != NULL; elem = elem->next) { - LinphoneFriend *friend = (LinphoneFriend *)elem->data; - if (ms_list_find(friend->insubs, op)) return friend; + LinphoneFriend *lf = (LinphoneFriend *)elem->data; + if (ms_list_find(lf->insubs, op)) return lf; } return NULL; } @@ -363,8 +363,8 @@ LinphoneFriend * linphone_friend_list_find_friend_by_inc_subscribe(const Linphon LinphoneFriend * linphone_friend_list_find_friend_by_out_subscribe(const LinphoneFriendList *list, SalOp *op) { const MSList *elem; for (elem = list->friends; elem != NULL; elem = elem->next) { - LinphoneFriend *friend = (LinphoneFriend *)elem->data; - if (friend->outsub && ((friend->outsub == op) || sal_op_is_forked_of(friend->outsub, op))) return friend; + LinphoneFriend *lf = (LinphoneFriend *)elem->data; + if (lf->outsub && ((lf->outsub == op) || sal_op_is_forked_of(lf->outsub, op))) return lf; } return NULL; } @@ -402,8 +402,8 @@ void linphone_friend_list_update_subscriptions(LinphoneFriendList *list, Linphon if (xml_content != NULL) ms_free(xml_content); } else { for (elem = list->friends; elem != NULL; elem = elem->next) { - LinphoneFriend *friend = (LinphoneFriend *)elem->data; - linphone_friend_update_subscribes(friend, cfg, only_when_registered); + LinphoneFriend *lf = (LinphoneFriend *)elem->data; + linphone_friend_update_subscribes(lf, cfg, only_when_registered); } } } @@ -411,16 +411,16 @@ void linphone_friend_list_update_subscriptions(LinphoneFriendList *list, Linphon void linphone_friend_list_invalidate_subscriptions(LinphoneFriendList *list) { const MSList *elem; for (elem = list->friends; elem != NULL; elem = elem->next) { - LinphoneFriend *friend = (LinphoneFriend *)elem->data; - linphone_friend_invalidate_subscription(friend); + LinphoneFriend *lf = (LinphoneFriend *)elem->data; + linphone_friend_invalidate_subscription(lf); } } void linphone_friend_list_notify_presence(LinphoneFriendList *list, LinphonePresenceModel *presence) { const MSList *elem; for(elem = list->friends; elem != NULL; elem = elem->next) { - LinphoneFriend *friend = (LinphoneFriend *)elem->data; - linphone_friend_notify(friend, presence); + LinphoneFriend *lf = (LinphoneFriend *)elem->data; + linphone_friend_notify(lf, presence); } } diff --git a/coreapi/private.h b/coreapi/private.h index 849095687..ab0327b9a 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -403,7 +403,7 @@ void linphone_core_friends_storage_close(LinphoneCore *lc); void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf); void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf); MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc); -LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *friend); +LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf); int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, socklen_t *socklen, int default_port); From 2af49f57001e7a07d2e21457fcac1244bb6b8401 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 24 Dec 2015 12:05:51 +0100 Subject: [PATCH 034/121] Updated ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 813aa6164..853609fcd 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 813aa6164aadcae5dbb2ea19b1f47deb8ce329f1 +Subproject commit 853609fcd048843752c244f1f335a9a664c2db93 From aa2a82ceae9e1d000a273e3792357d2863aff1f6 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 24 Dec 2015 14:55:44 +0100 Subject: [PATCH 035/121] Added JNI wrapper for friends/vcards import/export methods + setFriendsDatabasePath --- coreapi/linphonecore_jni.cc | 27 +++++++++++++++---- .../org/linphone/core/LinphoneCore.java | 16 +++++++++++ .../org/linphone/core/LinphoneCoreImpl.java | 17 ++++++++++++ 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 24df9fde4..4b2d3ec26 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1355,16 +1355,21 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_stopRinging(JNIEnv* env, linphone_core_stop_ringing((LinphoneCore*)lc); } -extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setChatDatabasePath(JNIEnv* env, jobject thiz, jlong lc, jstring jpath) { +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setChatDatabasePath(JNIEnv* env, jobject thiz, jlong lc, jstring jpath) { const char* path = env->GetStringUTFChars(jpath, NULL); linphone_core_set_chat_database_path((LinphoneCore*)lc, path); env->ReleaseStringUTFChars(jpath, path); } -extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setCallLogsDatabasePath( JNIEnv* env, jobject thiz, jlong lc, jstring jpath) { - const char* path = env->GetStringUTFChars(jpath, NULL); - linphone_core_set_call_logs_database_path((LinphoneCore*)lc, path); - env->ReleaseStringUTFChars(jpath, path); +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setCallLogsDatabasePath( JNIEnv* env, jobject thiz, jlong lc, jstring jpath) { + const char* path = env->GetStringUTFChars(jpath, NULL); + linphone_core_set_call_logs_database_path((LinphoneCore*)lc, path); + env->ReleaseStringUTFChars(jpath, path); +} +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setFriendsDatabasePath( JNIEnv* env, jobject thiz, jlong lc, jstring jpath) { + const char* path = env->GetStringUTFChars(jpath, NULL); + linphone_core_set_friends_database_path((LinphoneCore*)lc, path); + env->ReleaseStringUTFChars(jpath, path); } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPrimaryContact2(JNIEnv* env, jobject thiz, jlong lc, jstring jcontact) { @@ -1940,6 +1945,18 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_addFriend(JNIEnv* env linphone_core_add_friend((LinphoneCore*)lc,(LinphoneFriend*)aFriend); } +extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_importFriendsFromVCardFile(JNIEnv* env, jobject thiz, jlong lc, jstring jpath) { + const char* path = env->GetStringUTFChars(jpath, NULL); + return linphone_core_import_friends_from_vcard4_file((LinphoneCore*)lc, path); + env->ReleaseStringUTFChars(jpath, path); +} + +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_exportFriendsToVCardFile(JNIEnv* env, jobject thiz, jlong lc, jstring jpath) { + const char* path = env->GetStringUTFChars(jpath, NULL); + linphone_core_export_friends_as_vcard4_file((LinphoneCore*)lc, path); + env->ReleaseStringUTFChars(jpath, path); +} + extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setFriendList(JNIEnv* env ,jobject thiz ,jlong lc diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index bb36434da..f1ab3af41 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -1906,6 +1906,12 @@ public interface LinphoneCore { */ public void setCallLogsDatabasePath(String path); + /** + * Sets the path to the database where the friends will be stored (if enabled) + * @param path the database where the friends will be stored. + */ + public void setFriendsDatabasePath(String path); + /** * Gets the chat rooms * @return an array of LinphoneChatRoom @@ -2241,4 +2247,14 @@ public interface LinphoneCore { */ public int getNortpTimeout(); + /** + * Imports LinphoneFriends from a vCard 4 file + * @return the number of friend imported + **/ + public int importFriendsFromVCardFile(String file); + + /** + * Exports LinphoneFriends to a vCard 4 file + **/ + public void exportFriendsToVCardFile(String file); } diff --git a/java/impl/org/linphone/core/LinphoneCoreImpl.java b/java/impl/org/linphone/core/LinphoneCoreImpl.java index 46f6d6352..88af94b15 100644 --- a/java/impl/org/linphone/core/LinphoneCoreImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreImpl.java @@ -165,6 +165,7 @@ class LinphoneCoreImpl implements LinphoneCore { private native String getPrimaryContactDisplayName(long nativePtr); private native void setChatDatabasePath(long nativePtr, String path); private native void setCallLogsDatabasePath(long nativePtr, String path); + private native void setFriendsDatabasePath(long nativePtr, String path); private native long[] getChatRooms(long nativePtr); private native int migrateToMultiTransport(long nativePtr); private native void migrateCallLogs(long nativePtr); @@ -1196,6 +1197,10 @@ class LinphoneCoreImpl implements LinphoneCore { public synchronized void setCallLogsDatabasePath(String path) { setCallLogsDatabasePath(nativePtr, path); } + + public synchronized void setFriendsDatabasePath(String path) { + setFriendsDatabasePath(nativePtr, path); + } public synchronized LinphoneChatRoom[] getChatRooms() { long[] typesPtr = getChatRooms(nativePtr); @@ -1599,4 +1604,16 @@ class LinphoneCoreImpl implements LinphoneCore { public int getNortpTimeout(){ return getNortpTimeout(nativePtr); } + + private native int importFriendsFromVCardFile(long nativePtr, String file); + @Override + public int importFriendsFromVCardFile(String file) { + return importFriendsFromVCardFile(nativePtr, file); + } + + private native void exportFriendsToVCardFile(long nativePtr, String file); + @Override + public void exportFriendsToVCardFile(String file) { + exportFriendsToVCardFile(nativePtr, file); + } } From 4d454fdfd5a69080a655753481f8d0f49a339196 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 24 Dec 2015 16:11:28 +0100 Subject: [PATCH 036/121] Fix importFriends JNI method --- coreapi/linphonecore_jni.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 4b2d3ec26..aa65ee784 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1947,8 +1947,9 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_addFriend(JNIEnv* env extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_importFriendsFromVCardFile(JNIEnv* env, jobject thiz, jlong lc, jstring jpath) { const char* path = env->GetStringUTFChars(jpath, NULL); - return linphone_core_import_friends_from_vcard4_file((LinphoneCore*)lc, path); + int count = linphone_core_import_friends_from_vcard4_file((LinphoneCore*)lc, path); env->ReleaseStringUTFChars(jpath, path); + return count; } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_exportFriendsToVCardFile(JNIEnv* env, jobject thiz, jlong lc, jstring jpath) { From f0428f5c862f21dae2af422252a82c87db72c972 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 29 Dec 2015 11:26:46 +0100 Subject: [PATCH 037/121] Added LinphoneFriend setName/getName APIs to JNI layer --- coreapi/linphonecore_jni.cc | 18 ++++++++++++++++++ .../org/linphone/core/LinphoneFriend.java | 10 ++++++++++ .../org/linphone/core/LinphoneFriendImpl.java | 12 ++++++++++++ 3 files changed, 40 insertions(+) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index aa65ee784..20f0615c6 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -3096,12 +3096,22 @@ extern "C" void Java_org_linphone_core_LinphoneFriendImpl_setAddress(JNIEnv* en linphone_friend_set_address((LinphoneFriend*)ptr,(LinphoneAddress*)linphoneAddress); } +extern "C" void Java_org_linphone_core_LinphoneFriendImpl_setName(JNIEnv* env + ,jobject thiz + ,jlong ptr + ,jstring jname) { + const char* name = env->GetStringUTFChars(jname, NULL); + linphone_friend_set_name((LinphoneFriend*)ptr, name); + env->ReleaseStringUTFChars(jname, name); +} + extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_setRLSUri(JNIEnv* env ,jobject thiz ,jlong ptr ,jstring jrlsUri) { const char* uri = env->GetStringUTFChars(jrlsUri, NULL); linphone_friend_list_set_rls_uri((LinphoneFriendList*)ptr,uri); + env->ReleaseStringUTFChars(jrlsUri, uri); } extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_addFriend(JNIEnv* env @@ -3127,6 +3137,14 @@ extern "C" jlong Java_org_linphone_core_LinphoneFriendImpl_getAddress(JNIEnv* e ,jlong ptr) { return (jlong)linphone_friend_get_address((LinphoneFriend*)ptr); } + +extern "C" jstring Java_org_linphone_core_LinphoneFriendImpl_getName(JNIEnv* env + ,jobject thiz + ,jlong ptr) { + const char *name = linphone_friend_get_name((LinphoneFriend*)ptr); + return name ? env->NewStringUTF(name) : NULL; +} + extern "C" void Java_org_linphone_core_LinphoneFriendImpl_setIncSubscribePolicy(JNIEnv* env ,jobject thiz ,jlong ptr diff --git a/java/common/org/linphone/core/LinphoneFriend.java b/java/common/org/linphone/core/LinphoneFriend.java index b9080bd94..b16ca9b63 100644 --- a/java/common/org/linphone/core/LinphoneFriend.java +++ b/java/common/org/linphone/core/LinphoneFriend.java @@ -145,4 +145,14 @@ public interface LinphoneFriend { * @return The reference key of the friend. **/ String getRefKey(); + /** + * Set a name for this friend + * @param name + */ + void setName(String name); + /** + * get name of this friend + * @return + */ + String getName(); } diff --git a/java/impl/org/linphone/core/LinphoneFriendImpl.java b/java/impl/org/linphone/core/LinphoneFriendImpl.java index ba47eccb4..b6114b3e6 100644 --- a/java/impl/org/linphone/core/LinphoneFriendImpl.java +++ b/java/impl/org/linphone/core/LinphoneFriendImpl.java @@ -118,4 +118,16 @@ class LinphoneFriendImpl implements LinphoneFriend, Serializable { public String getRefKey(){ return getRefKey(nativePtr); } + + private native void setName(long nativePtr, String name); + @Override + public void setName(String name) { + setName(nativePtr, name); + } + + private native String getName(long nativePtr); + @Override + public String getName() { + return getName(nativePtr); + } } From a06241619e87465f941fae6b92ce94f7ca495b8a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 29 Dec 2015 15:55:16 +0100 Subject: [PATCH 038/121] Updated oRTP with fix for linphone-desktop build for win32 platform --- oRTP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oRTP b/oRTP index d9df9695a..8f4051b23 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit d9df9695a2fdb788e66d838cc5a94fa2b76ae532 +Subproject commit 8f4051b2366aecfa96487d3ad22fd0c15a972759 From bdc8dad0f08fa6409c38fa15cfcf600b1456064b Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 30 Dec 2015 11:58:09 +0100 Subject: [PATCH 039/121] Fix build with Visual Studio 2015. --- coreapi/presence.c | 4 ++-- coreapi/private.h | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/coreapi/presence.c b/coreapi/presence.c index ea6744ef6..e398843c9 100644 --- a/coreapi/presence.c +++ b/coreapi/presence.c @@ -157,7 +157,7 @@ static void presence_activity_delete(LinphonePresenceActivity *activity) { static time_t parse_timestamp(const char *timestamp) { struct tm ret; time_t seconds; -#ifdef LINPHONE_WINDOWS_UNIVERSAL +#if defined(LINPHONE_WINDOWS_UNIVERSAL) || defined(LINPHONE_MSC_VER_GREATER_19) long adjust_timezone; #else time_t adjust_timezone; @@ -174,7 +174,7 @@ static time_t parse_timestamp(const char *timestamp) { ms_error("mktime() failed: %s", strerror(errno)); return (time_t)-1; } -#ifdef LINPHONE_WINDOWS_UNIVERSAL +#if defined(LINPHONE_WINDOWS_UNIVERSAL) || defined(LINPHONE_MSC_VER_GREATER_19) _get_timezone(&adjust_timezone); #else adjust_timezone = timezone; diff --git a/coreapi/private.h b/coreapi/private.h index ab0327b9a..d8dc08c50 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -111,6 +111,11 @@ extern "C" { #endif #endif #endif +#ifdef _MSC_VER +#if (_MSC_VER >= 1900) +#define LINPHONE_MSC_VER_GREATER_19 +#endif +#endif struct _LinphoneCallParams{ belle_sip_object_t base; From 8cc1a6d6f081255986cbdff8bbfed0801953a809 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 30 Dec 2015 17:31:04 +0100 Subject: [PATCH 040/121] Fix windows compilation when belcard isn't found/enabled --- coreapi/vcard_stubs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/coreapi/vcard_stubs.c b/coreapi/vcard_stubs.c index 3bb7bed9e..d50ab29b9 100644 --- a/coreapi/vcard_stubs.c +++ b/coreapi/vcard_stubs.c @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "vcard.h" struct _LinphoneVCard { + void *dummy; }; LinphoneVCard* linphone_vcard_new(void) { From ecbeb8a9ee7d88ec0e991a3b96aa4dc9ed4e1392 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 30 Dec 2015 17:49:53 +0100 Subject: [PATCH 041/121] Attempt to fix VS compil when building without vCard support --- tester/vcard_tester.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index da8bb8ba2..ce1918101 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -194,6 +194,7 @@ test_t vcard_tests[] = { { "Friends storage in sqlite database", friends_sqlite_storage }, #endif #endif + { }, }; test_suite_t vcard_test_suite = { From 0f54b50e764c4294cac001512ef5198413511b7f Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 31 Dec 2015 10:09:50 +0100 Subject: [PATCH 042/121] Added dummy test to please VS... --- tester/vcard_tester.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index ce1918101..4b47e622d 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -182,6 +182,10 @@ end: linphone_core_manager_destroy(manager); } #endif +#else +static void dummy_test(void) { + +} #endif test_t vcard_tests[] = { @@ -192,9 +196,10 @@ test_t vcard_tests[] = { { "Friends working if no db set", friends_if_no_db_set }, { "Friends storage migration from rc to db", friends_migration }, { "Friends storage in sqlite database", friends_sqlite_storage }, +#endif +#else + { "Dummy test", dummy_test } #endif -#endif - { }, }; test_suite_t vcard_test_suite = { From f85edbaa9e264824837b9e09f7788e42ca55b8f9 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 5 Jan 2016 11:19:25 +0100 Subject: [PATCH 043/121] Started carddav code --- coreapi/Makefile.am | 12 +++++++----- coreapi/carddav.cc | 28 ++++++++++++++++++++++++++++ coreapi/carddav.h | 35 +++++++++++++++++++++++++++++++++++ coreapi/linphonecore.c | 10 ++++++++++ coreapi/linphonecore.h | 7 +++++++ coreapi/private.h | 1 + 6 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 coreapi/carddav.cc create mode 100644 coreapi/carddav.h diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 853113796..728a9fe14 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -42,7 +42,8 @@ linphone_include_HEADERS=\ lpconfig.h \ sipsetup.h \ xml2lpc.h \ - xmlrpc.h + xmlrpc.h \ + carddav.h lib_LTLIBRARIES=liblinphone.la @@ -90,8 +91,10 @@ liblinphone_la_SOURCES=\ xml.c \ xmlrpc.c \ vtables.c \ + carddav.cc \ $(GITVERSION_FILE) +liblinphone_la_CXXFLAGS=-std=c++11 if BUILD_UPNP liblinphone_la_SOURCES+=upnp.c upnp.h endif @@ -118,7 +121,6 @@ endif if BUILD_VCARD liblinphone_la_SOURCES+=vcard.cc vcard.h -liblinphone_la_CXXFLAGS=-std=c++11 else liblinphone_la_SOURCES+=vcard_stubs.c vcard.h endif @@ -155,14 +157,14 @@ liblinphone_la_LIBADD= \ AM_CPPFLAGS=\ -I$(top_srcdir) -I$(top_srcdir)/include -I$(builddir) \ - $(ORTP_CFLAGS) \ - $(MEDIASTREAMER_CFLAGS) + $(ORTP_CFLAGS) \ + $(MEDIASTREAMER_CFLAGS) COMMON_CFLAGS=\ $(STRICT_OPTIONS) \ -DIN_LINPHONE \ $(SIPSTACK_CFLAGS) \ - -DENABLE_TRACE \ + -DENABLE_TRACE \ -DLOG_DOMAIN=\"LinphoneCore\" \ $(IPV6_CFLAGS) \ -DORTP_INET6 \ diff --git a/coreapi/carddav.cc b/coreapi/carddav.cc new file mode 100644 index 000000000..1c96ab246 --- /dev/null +++ b/coreapi/carddav.cc @@ -0,0 +1,28 @@ +/* +carddav.cc +Copyright (C) 2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "carddav.h" + +extern "C" void linphone_core_start_carddav_sync(LinphoneCore *lc) { +#ifdef VCARD_ENABLED + +#else + ms_error("vCard isn't available (maybe it wasn't compiled), can't do CardDAV sync"); +#endif +} \ No newline at end of file diff --git a/coreapi/carddav.h b/coreapi/carddav.h new file mode 100644 index 000000000..5d85838e5 --- /dev/null +++ b/coreapi/carddav.h @@ -0,0 +1,35 @@ +/* +carddav.h +Copyright (C) 2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef LINPHONE_CARDDAV_H +#define LINPHONE_CARDDAV_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "linphonecore.h" + +LINPHONE_PUBLIC void linphone_core_start_carddav_sync(LinphoneCore *lc); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 2878d6d7f..863f8dae7 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -7436,3 +7436,13 @@ const char *linphone_stream_type_to_string(const LinphoneStreamType type) { } return "INVALID"; } + +void linphone_core_set_carddav_server_url(LinphoneCore *lc, const char *carddav_server_url) { + if (lc->carddav_server_url) { + ms_free(lc->carddav_server_url); + lc->carddav_server_url = NULL; + } + if (carddav_server_url) { + lc->carddav_server_url = ms_strdup(carddav_server_url); + } +} diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 2a4f1309a..3ee4144e4 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -4252,6 +4252,13 @@ LINPHONE_PUBLIC LinphoneTransportType linphone_transport_parse(const char* trans */ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *lc); +/** + * Sets the CardDAV server URL + * @param lc LinphoneCore object + * @param carddav_server_url the URL to the CardDAV server + */ +LINPHONE_PUBLIC void linphone_core_set_carddav_server_url(LinphoneCore *lc, const char *carddav_server_url); + #ifdef __cplusplus } #endif diff --git a/coreapi/private.h b/coreapi/private.h index 705f56605..7f774cbfe 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -972,6 +972,7 @@ struct _LinphoneCore jmethodID multicast_lock_acquire_id; jmethodID multicast_lock_release_id; #endif + char *carddav_server_url; }; From a8e6cc908fff1121ae0cfc2527c2a21cdea0e3d5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 5 Jan 2016 16:31:20 +0100 Subject: [PATCH 044/121] More work on CardDAV sync: doing propfind and addressbook-query requests --- coreapi/Makefile.am | 4 +- coreapi/carddav.c | 234 ++++++++++++++++++++++++++++++++++++++ coreapi/carddav.cc | 28 ----- coreapi/carddav.h | 112 +++++++++++++++++- coreapi/linphonecore.c | 81 ++++++++++++- coreapi/linphonecore.h | 54 +++++++++ coreapi/private.h | 53 ++++++++- tester/Makefile.am | 3 +- tester/rcfiles/carddav_rc | 11 ++ tester/vcard_tester.c | 25 +++- 10 files changed, 562 insertions(+), 43 deletions(-) create mode 100644 coreapi/carddav.c delete mode 100644 coreapi/carddav.cc create mode 100644 tester/rcfiles/carddav_rc diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 728a9fe14..e6fe1eeef 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -91,10 +91,9 @@ liblinphone_la_SOURCES=\ xml.c \ xmlrpc.c \ vtables.c \ - carddav.cc \ + carddav.c \ $(GITVERSION_FILE) -liblinphone_la_CXXFLAGS=-std=c++11 if BUILD_UPNP liblinphone_la_SOURCES+=upnp.c upnp.h endif @@ -121,6 +120,7 @@ endif if BUILD_VCARD liblinphone_la_SOURCES+=vcard.cc vcard.h +liblinphone_la_CXXFLAGS=-std=c++11 else liblinphone_la_SOURCES+=vcard_stubs.c vcard.h endif diff --git a/coreapi/carddav.c b/coreapi/carddav.c new file mode 100644 index 000000000..55c8860f6 --- /dev/null +++ b/coreapi/carddav.c @@ -0,0 +1,234 @@ +/* +carddav.c +Copyright (C) 2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "linphonecore.h" +#include "private.h" + +LinphoneCardDavContext* linphone_core_create_carddav_context(LinphoneCore *lc) { + LinphoneCardDavContext *carddav_context = NULL; + + if (!lc) { + return NULL; + } + +#ifdef VCARD_ENABLED + carddav_context = (LinphoneCardDavContext *)ms_new0(LinphoneCardDavContext, 1); + carddav_context->lc = lc; + carddav_context->server_url = linphone_core_get_carddav_server_url(lc); + carddav_context->ctag = linphone_core_get_carddav_last_ctag(lc); + carddav_context->username = linphone_core_get_carddav_username(lc); + carddav_context->password = linphone_core_get_carddav_password(lc); + carddav_context->ha1 = linphone_core_get_carddav_ha1(lc); +#else + ms_error("vCard isn't available (maybe it wasn't compiled), can't do CardDAV sync"); +#endif + return carddav_context; +} + +void linphone_carddav_destroy(LinphoneCardDavContext *cdc) { + if (cdc) { + ms_free(cdc); + } +} + +void linphone_carddav_set_user_data(LinphoneCardDavContext *cdc, void *ud) { + cdc->user_data = ud; +} + +void* linphone_carddav_get_user_data(LinphoneCardDavContext *cdc) { + return cdc->user_data; +} + +static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList *vCards) { + if (vCards != NULL && ms_list_size(vCards) > 0) { + //MSList *localFriends = linphone_core_fetch_friends_from_db(cdc->lc); + //TODO: find out if there are new/delete URLs and compare eTags with the current vCards + } + if (cdc->sync_done_cb) { + cdc->sync_done_cb(cdc, TRUE, "TODO: remove lated"); + } +} + +static void linphone_carddav_ctag_fetched(LinphoneCardDavContext *cdc, int ctag) { + if (ctag == -1 || ctag > cdc->ctag) { + cdc->ctag = ctag; + linphone_carddav_fetch_vcards(cdc); + } else { + ms_message("No changes found on server, skipping sync"); + if (cdc->sync_done_cb) { + cdc->sync_done_cb(cdc, TRUE, "Synchronization skipped because cTag already up to date"); + } + } +} + +void linphone_carddav_synchronize(LinphoneCardDavContext *cdc) { + linphone_carddav_get_current_ctag(cdc); +} + +static void process_response_from_carddav_request(void *data, const belle_http_response_event_t *event) { + LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data; + + if (event->response) { + int code = belle_http_response_get_status_code(event->response); + if (code == 207 || code == 200) { + const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response); + ms_message("CardDAV query response body: %s", body); + query->status = LinphoneCardDavQueryStatusOk; + switch(query->type) { + case LinphoneCardDavQueryTypePropfind: + linphone_carddav_ctag_fetched(query->context, 0);//TODO parse value from body + break; + case LinphoneCardDavQueryTypeAddressbookQuery: + linphone_carddav_vcards_fetched(query->context, NULL);//TODO parse value from body + break; + case LinphoneCardDavQueryTypeAddressbookMultiget: + break; + } + } else { + query->status = LinphoneCardDavQueryStatusFailed; + } + } + ms_free(query); +} + +static void process_io_error_from_carddav_request(void *data, const belle_sip_io_error_event_t *event) { + LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data; + ms_error("I/O Error during CardDAV request sending"); + query->status = LinphoneCardDavQueryStatusFailed; + ms_free(query); + if (query->context->sync_done_cb) { + query->context->sync_done_cb(query->context, FALSE, "I/O Error during CardDAV request sending"); + } +} + +static void process_auth_requested_from_carddav_request(void *data, belle_sip_auth_event_t *event) { + LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data; + LinphoneCardDavContext *context = query->context; + + if (context->username && (context->password || context->ha1)) { + belle_sip_auth_event_set_username(event, context->username); + if (context->password) { + belle_sip_auth_event_set_passwd(event, context->password); + } + if (context->ha1) { + belle_sip_auth_event_set_ha1(event, context->ha1); + } + } else { + query->status = LinphoneCardDavQueryStatusFailed; + ms_error("Authentication error during CardDAV request sending"); + if (query->context->sync_done_cb) { + query->context->sync_done_cb(query->context, FALSE, "Authentication error during CardDAV request sending"); + } + } +} + +static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { + belle_http_request_listener_callbacks_t cbs = { 0 }; + belle_http_request_listener_t *l = NULL; + belle_generic_uri_t *uri = NULL; + belle_http_request_t *req = NULL; + belle_sip_memory_body_handler_t *bh = NULL; + + uri = belle_generic_uri_parse(query->url); + if (!uri) { + belle_sip_error("Could not send request, URL %s is invalid", query->url); + query->status = LinphoneCardDavQueryStatusFailed; + return; + } + req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), belle_sip_header_create("Depth", query->depth), NULL); + if (!req) { + belle_sip_object_unref(uri); + belle_sip_error("Could not create belle_http_request_t"); + query->status = LinphoneCardDavQueryStatusFailed; + return; + } + query->status = LinphoneCardDavQueryStatusPending; + + bh = belle_sip_memory_body_handler_new_copy_from_buffer(query->body, strlen(query->body), NULL, NULL); + belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(bh)); + + cbs.process_response = process_response_from_carddav_request; + cbs.process_io_error = process_io_error_from_carddav_request; + cbs.process_auth_requested = process_auth_requested_from_carddav_request; + l = belle_http_request_listener_create_from_callbacks(&cbs, query); + belle_http_provider_send_request(query->context->lc->http_provider, req, l); +} + +void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { + //TODO +} + +void linphone_carddav_delete_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { + //TODO +} + +void linphone_carddav_set_synchronization_done_callback(LinphoneCardDavContext *cdc, LinphoneCardDavSynchronizationDoneCb cb) { + cdc->sync_done_cb = cb; +} + +static LinphoneCardDavQuery* linphone_carddav_create_propfind_query(LinphoneCardDavContext *cdc) { + LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); + query->context = cdc; + query->depth = "0"; + query->body = ""; + query->method = "PROPFIND"; + query->url = cdc->server_url; + query->type = LinphoneCardDavQueryTypePropfind; + query->status = LinphoneCardDavQueryStatusIdle; + return query; +} + +void linphone_carddav_get_current_ctag(LinphoneCardDavContext *cdc) { + LinphoneCardDavQuery *query = linphone_carddav_create_propfind_query(cdc); + linphone_carddav_send_query(query); +} + +static LinphoneCardDavQuery* linphone_carddav_create_addressbook_query(LinphoneCardDavContext *cdc) { + LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); + query->context = cdc; + query->depth = "1"; + query->body = ""; + query->method = "REPORT"; + query->url = cdc->server_url; + query->type = LinphoneCardDavQueryTypeAddressbookQuery; + query->status = LinphoneCardDavQueryStatusIdle; + return query; +} + +void linphone_carddav_fetch_vcards(LinphoneCardDavContext *cdc) { + LinphoneCardDavQuery *query = linphone_carddav_create_addressbook_query(cdc); + linphone_carddav_send_query(query); +} + +static LinphoneCardDavQuery* linphone_carddav_create_addressbook_multiget_query(LinphoneCardDavContext *cdc, MSList *vcards) { + LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); + query->context = cdc; + query->depth = "1"; + query->method = "REPORT"; + query->url = cdc->server_url; + query->type = LinphoneCardDavQueryTypeAddressbookMultiget; + query->status = LinphoneCardDavQueryStatusIdle; + //TODO: body + return query; +} + +void linphone_carddav_pull_vcards(LinphoneCardDavContext *cdc, MSList *vcards_to_pull) { + LinphoneCardDavQuery *query = linphone_carddav_create_addressbook_multiget_query(cdc, vcards_to_pull); + linphone_carddav_send_query(query); +} \ No newline at end of file diff --git a/coreapi/carddav.cc b/coreapi/carddav.cc deleted file mode 100644 index 1c96ab246..000000000 --- a/coreapi/carddav.cc +++ /dev/null @@ -1,28 +0,0 @@ -/* -carddav.cc -Copyright (C) 2015 Belledonne Communications SARL - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "carddav.h" - -extern "C" void linphone_core_start_carddav_sync(LinphoneCore *lc) { -#ifdef VCARD_ENABLED - -#else - ms_error("vCard isn't available (maybe it wasn't compiled), can't do CardDAV sync"); -#endif -} \ No newline at end of file diff --git a/coreapi/carddav.h b/coreapi/carddav.h index 5d85838e5..8cb4b5bc1 100644 --- a/coreapi/carddav.h +++ b/coreapi/carddav.h @@ -23,10 +23,118 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef __cplusplus extern "C" { #endif + +typedef struct _LinphoneCardDavContext LinphoneCardDavContext; -#include "linphonecore.h" +typedef enum _LinphoneCardDavQueryType { + LinphoneCardDavQueryTypePropfind, + LinphoneCardDavQueryTypeAddressbookQuery, + LinphoneCardDavQueryTypeAddressbookMultiget +} LinphoneCardDavQueryType; -LINPHONE_PUBLIC void linphone_core_start_carddav_sync(LinphoneCore *lc); +typedef enum _LinphoneCardDavQueryStatus { + LinphoneCardDavQueryStatusIdle, + LinphoneCardDavQueryStatusPending, + LinphoneCardDavQueryStatusOk, + LinphoneCardDavQueryStatusFailed +} LinphoneCardDavQueryStatus; + +typedef struct _LinphoneCardDavQuery LinphoneCardDavQuery; + +typedef struct _LinphoneCardDavResponse LinphoneCardDavResponse; + +/** + * Callback used to notify a new contact has been created on the CardDAV server +**/ +typedef void (*LinphoneCardDavContactCreatedCb)(LinphoneFriend *lf); + +/** + * Callback used to notify a contact has been updated on the CardDAV server +**/ +typedef void (*LinphoneCardDavContactUpdatedCb)(LinphoneFriend *lf); + +/** + * Callback used to notify a contact has been removed on the CardDAV server +**/ +typedef void (*LinphoneCardDavContactRemovedCb)(LinphoneFriend *lf); + +/** + * Callback used to notify a contact has been removed on the CardDAV server +**/ +typedef void (*LinphoneCardDavSynchronizationDoneCb)(LinphoneCardDavContext *cdc, bool_t success, const char *message); + +/** + * Creates a CardDAV context for all related operations + * @param lc LinphoneCore object + * @return LinphoneCardDavContext object if vCard support is enabled and server URL is available, NULL otherwise + */ +LINPHONE_PUBLIC LinphoneCardDavContext* linphone_core_create_carddav_context(LinphoneCore *lc); + +/** + * Deletes a LinphoneCardDavContext object + * @param cdc LinphoneCardDavContext object + */ +LINPHONE_PUBLIC void linphone_carddav_destroy(LinphoneCardDavContext *cdc); + +/** + * Sets a user pointer to the LinphoneCardDAVContext object + * @param cdc LinphoneCardDavContext object + * @param ud The user data pointer + */ +LINPHONE_PUBLIC void linphone_carddav_set_user_data(LinphoneCardDavContext *cdc, void *ud); + +/** + * Gets the user pointer set in the LinphoneCardDAVContext object + * @param cdc LinphoneCardDavContext object + * @return The user data pointer if set, NULL otherwise + */ +LINPHONE_PUBLIC void* linphone_carddav_get_user_data(LinphoneCardDavContext *cdc); + +/** + * Starts a synchronization with the remote server to update local friends with server changes + * @param cdc LinphoneCardDavContext object + */ +LINPHONE_PUBLIC void linphone_carddav_synchronize(LinphoneCardDavContext *cdc); + +/** + * Sends a LinphoneFriend to the CardDAV server for update or creation + * @param cdc LinphoneCardDavContext object + * @param lf a LinphoneFriend object to update/create on the server + */ +LINPHONE_PUBLIC void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf); + +/** + * Deletes a LinphoneFriend on the CardDAV server + * @param cdc LinphoneCardDavContext object + * @param lf a LinphoneFriend object to delete on the server + */ +LINPHONE_PUBLIC void linphone_carddav_delete_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf); + +/** + * Set the synchronization done callback. + * @param cdc LinphoneCardDavContext object + * @param cb The synchronization done callback to be used. + */ +LINPHONE_PUBLIC void linphone_carddav_set_synchronization_done_callback(LinphoneCardDavContext *cdc, LinphoneCardDavSynchronizationDoneCb cb); + +/** + * Retrieves the current cTag value for the remote server + * @param cdc LinphoneCardDavContext object + */ +void linphone_carddav_get_current_ctag(LinphoneCardDavContext *cdc); + +/** + * Retrieves a list of all the vCards on server side to be able to detect changes + * @param cdc LinphoneCardDavContext object + */ +void linphone_carddav_fetch_vcards(LinphoneCardDavContext *cdc); + +/** + * Download asked vCards from the server + * @param cdc LinphoneCardDavContext object + * @param vcards_to_pull a MSList of LinphoneCardDavResponse objects with at least the url field filled + */ +void linphone_carddav_pull_vcards(LinphoneCardDavContext *cdc, MSList *vcards_to_pull); #ifdef __cplusplus } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 863f8dae7..3a306ad78 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -7437,12 +7437,81 @@ const char *linphone_stream_type_to_string(const LinphoneStreamType type) { return "INVALID"; } +/***************************************************************************** + * CardDAV interface * + ****************************************************************************/ + void linphone_core_set_carddav_server_url(LinphoneCore *lc, const char *carddav_server_url) { - if (lc->carddav_server_url) { - ms_free(lc->carddav_server_url); - lc->carddav_server_url = NULL; - } - if (carddav_server_url) { - lc->carddav_server_url = ms_strdup(carddav_server_url); + if (lc && carddav_server_url) { + LpConfig *lpc = linphone_core_get_config(lc); + lp_config_set_string(lpc, "carddav", "server_url", carddav_server_url); } } + +const char *linphone_core_get_carddav_server_url(LinphoneCore *lc) { + if (lc) { + LpConfig *lpc = linphone_core_get_config(lc); + return lp_config_get_string(lpc, "carddav", "server_url", NULL); + } + return NULL; +} + +void linphone_core_set_carddav_username(LinphoneCore *lc, const char *username) { + if (lc && username) { + LpConfig *lpc = linphone_core_get_config(lc); + lp_config_set_string(lpc, "carddav", "username", username); + } +} + +const char *linphone_core_get_carddav_username(LinphoneCore *lc) { + if (lc) { + LpConfig *lpc = linphone_core_get_config(lc); + return lp_config_get_string(lpc, "carddav", "username", NULL); + } + return NULL; +} + +void linphone_core_set_carddav_password(LinphoneCore *lc, const char *password) { + if (lc && password) { + LpConfig *lpc = linphone_core_get_config(lc); + lp_config_set_string(lpc, "carddav", "password", password); + } +} + +const char *linphone_core_get_carddav_password(LinphoneCore *lc) { + if (lc) { + LpConfig *lpc = linphone_core_get_config(lc); + return lp_config_get_string(lpc, "carddav", "password", NULL); + } + return NULL; +} + +void linphone_core_set_carddav_ha1(LinphoneCore *lc, const char *ha1) { + if (lc && ha1) { + LpConfig *lpc = linphone_core_get_config(lc); + lp_config_set_string(lpc, "carddav", "ha1", ha1); + } +} + +const char *linphone_core_get_carddav_ha1(LinphoneCore *lc) { + if (lc) { + LpConfig *lpc = linphone_core_get_config(lc); + return lp_config_get_string(lpc, "carddav", "ha1", NULL); + } + return NULL; +} + +void linphone_core_set_carddav_current_ctag(LinphoneCore *lc, int ctag) { + if (lc) { + LpConfig *lpc = linphone_core_get_config(lc); + lp_config_set_int(lpc, "carddav", "ctag", ctag); + } +} + +int linphone_core_get_carddav_last_ctag(LinphoneCore *lc) { + if (lc) { + LpConfig *lpc = linphone_core_get_config(lc); + return lp_config_get_int(lpc, "carddav", "ctag", -1); + } + return -1; +} \ No newline at end of file diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 3ee4144e4..235f09c62 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -410,6 +410,7 @@ LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy); #include "event.h" #include "linphonefriend.h" #include "xmlrpc.h" +#include "carddav.h" #else #include "linphone/buffer.h" #include "linphone/call_log.h" @@ -418,6 +419,7 @@ LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy); #include "linphone/event.h" #include "linphone/linphonefriend.h" #include "linphone/xmlrpc.h" +#include "linphone/carddav.h" #endif LINPHONE_PUBLIC LinphoneAddress * linphone_address_new(const char *addr); @@ -4252,6 +4254,10 @@ LINPHONE_PUBLIC LinphoneTransportType linphone_transport_parse(const char* trans */ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *lc); +/***************************************************************************** + * CardDAV interface * + ****************************************************************************/ + /** * Sets the CardDAV server URL * @param lc LinphoneCore object @@ -4259,6 +4265,54 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneCallParams *linphone_core_create_def */ LINPHONE_PUBLIC void linphone_core_set_carddav_server_url(LinphoneCore *lc, const char *carddav_server_url); +/** + * Gets the CardDAV server URL if set + * @param lc LinphoneCore object + * @return the URL to the CardDAV server if set, otherwise NULL + */ +LINPHONE_PUBLIC const char *linphone_core_get_carddav_server_url(LinphoneCore *lc); +/** + * Sets the CardDAV server username + * @param lc LinphoneCore object + * @param username the username for the CardDAV server + */ +LINPHONE_PUBLIC void linphone_core_set_carddav_username(LinphoneCore *lc, const char *username); + +/** + * Gets the CardDAV server username + * @param lc LinphoneCore object + * @return the username for the CardDAV server if set, otherwise NULL + */ +LINPHONE_PUBLIC const char *linphone_core_get_carddav_username(LinphoneCore *lc); + +/** + * Sets the CardDAV server password + * @param lc LinphoneCore object + * @param password the password for the CardDAV server + */ +LINPHONE_PUBLIC void linphone_core_set_carddav_password(LinphoneCore *lc, const char *password); + +/** + * Gets the CardDAV server password + * @param lc LinphoneCore object + * @return the password for the CardDAV server if set, otherwise NULL + */ +LINPHONE_PUBLIC const char *linphone_core_get_carddav_password(LinphoneCore *lc); + +/** + * Sets the CardDAV server hashed password + * @param lc LinphoneCore object + * @param ha1 the hashed password for the CardDAV server + */ +LINPHONE_PUBLIC void linphone_core_set_carddav_ha1(LinphoneCore *lc, const char *ha1); + +/** + * Gets the CardDAV server hashed password + * @param lc LinphoneCore object + * @return the hashed password for the CardDAV server if set, otherwise NULL + */ +LINPHONE_PUBLIC const char *linphone_core_get_carddav_ha1(LinphoneCore *lc); + #ifdef __cplusplus } #endif diff --git a/coreapi/private.h b/coreapi/private.h index 7f774cbfe..f3c21934d 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -972,7 +972,6 @@ struct _LinphoneCore jmethodID multicast_lock_acquire_id; jmethodID multicast_lock_release_id; #endif - char *carddav_server_url; }; @@ -1223,9 +1222,57 @@ struct _LinphoneAccountCreator { BELLE_SIP_DECLARE_VPTR(LinphoneAccountCreator); +/***************************************************************************** + * CardDAV interface * + ****************************************************************************/ + +struct _LinphoneCardDavContext { + LinphoneCore *lc; + int ctag; + const char *server_url; + const char *username; + const char *password; + const char *ha1; + void *user_data; + LinphoneCardDavContactCreatedCb contact_created_cb; + LinphoneCardDavContactUpdatedCb contact_updated_cb; + LinphoneCardDavContactRemovedCb contact_removed_cb; + LinphoneCardDavSynchronizationDoneCb sync_done_cb; +}; + +struct _LinphoneCardDavQuery { + LinphoneCardDavContext *context; + const char *url; + const char *method; + const char *body; + const char *depth; + LinphoneCardDavQueryType type; + LinphoneCardDavQueryStatus status; +}; + +struct _LinphoneCardDavResponse { + LinphoneCardDavContext *context; + const char *etag; + const char *url; + const char *vcard; +}; + +/** + * Sets the CardDAV server current cTag + * @param lc LinphoneCore object + * @param ctag the current cTag for the CardDAV server + */ +void linphone_core_set_carddav_current_ctag(LinphoneCore *lc, int ctag); + +/** + * Gets the CardDAV server last cTag + * @param lc LinphoneCore object + * @return the last cTag for the CardDAV server if set, otherwise -1 + */ +int linphone_core_get_carddav_last_ctag(LinphoneCore *lc); /***************************************************************************** - * REMOTE PROVISIONING FUNCTIONS * + * REMOTE PROVISIONING FUNCTIONS * ****************************************************************************/ void linphone_configuring_terminated(LinphoneCore *lc, LinphoneConfiguringState state, const char *message); @@ -1233,7 +1280,7 @@ int linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char LINPHONE_PUBLIC int linphone_remote_provisioning_load_file( LinphoneCore* lc, const char* file_path); /***************************************************************************** - * Player interface + * Player interface * ****************************************************************************/ struct _LinphonePlayer{ diff --git a/tester/Makefile.am b/tester/Makefile.am index d2da519a5..ec46807a9 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -69,7 +69,8 @@ RCFILES = \ rcfiles/stun_rc\ rcfiles/upnp_rc\ rcfiles/zero_length_params_rc\ - rcfiles/friends_rc + rcfiles/friends_rc\ + rcfiles/carddav_rc IMAGE_FILES = images/nowebcamCIF.jpg diff --git a/tester/rcfiles/carddav_rc b/tester/rcfiles/carddav_rc new file mode 100644 index 000000000..c4d35f470 --- /dev/null +++ b/tester/rcfiles/carddav_rc @@ -0,0 +1,11 @@ +[net] +mtu=1300 + +[sip] +ping_with_options=0 +sip_random_port=1 + +[carddav] +server_url=http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default +username=sylvain +ha1=4747ce2517a985f2fc20234a38f068b6 \ No newline at end of file diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 4b47e622d..7a1506cf1 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -19,6 +19,7 @@ #include "linphonecore.h" #include "private.h" #include "liblinphone_tester.h" +#include "carddav.h" #include @@ -182,6 +183,27 @@ end: linphone_core_manager_destroy(manager); } #endif + +static void carddav_sync_done(LinphoneCardDavContext *c, bool_t success, const char *message) { + BC_ASSERT_TRUE(success); + linphone_carddav_destroy(c); +} + +static void carddav_sync(void) { + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); + LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); + + BC_ASSERT_PTR_NOT_NULL_FATAL(c); + BC_ASSERT_PTR_NOT_NULL(c->server_url); + BC_ASSERT_PTR_NOT_NULL(c->username); + BC_ASSERT_PTR_NOT_NULL(c->ha1); + + linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); + linphone_carddav_synchronize(c); + + wait_for_until(manager->lc, NULL, NULL, 1, 1000); + linphone_core_manager_destroy(manager); +} #else static void dummy_test(void) { @@ -196,7 +218,8 @@ test_t vcard_tests[] = { { "Friends working if no db set", friends_if_no_db_set }, { "Friends storage migration from rc to db", friends_migration }, { "Friends storage in sqlite database", friends_sqlite_storage }, -#endif +#endif + { "CardDAV synchronization", carddav_sync } #else { "Dummy test", dummy_test } #endif From b5300c180c77edb108db2cdb6e8057ccd213be36 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 7 Jan 2016 13:04:43 +0100 Subject: [PATCH 045/121] Parse results for PROPFIND and REPORT requests --- coreapi/carddav.c | 183 +++++++++++++++++++++++++++++++++++------ coreapi/linphonecore.c | 4 +- coreapi/private.h | 1 + coreapi/xml.c | 8 ++ 4 files changed, 171 insertions(+), 25 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 55c8860f6..f1a63d073 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -55,30 +55,157 @@ void* linphone_carddav_get_user_data(LinphoneCardDavContext *cdc) { return cdc->user_data; } -static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList *vCards) { - if (vCards != NULL && ms_list_size(vCards) > 0) { - //MSList *localFriends = linphone_core_fetch_friends_from_db(cdc->lc); - //TODO: find out if there are new/delete URLs and compare eTags with the current vCards +void linphone_carddav_synchronize(LinphoneCardDavContext *cdc) { + linphone_carddav_get_current_ctag(cdc); +} + +static void linphone_carddav_sync_done(LinphoneCardDavContext *cdc, bool_t success, const char *msg) { + if (success) { + linphone_core_set_carddav_current_ctag(cdc->lc, cdc->ctag); } + if (cdc->sync_done_cb) { - cdc->sync_done_cb(cdc, TRUE, "TODO: remove lated"); + cdc->sync_done_cb(cdc, success, msg); } } +static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList *vCards) { + if (vCards != NULL && ms_list_size(vCards) > 0) { + //TODO: find out which one is new and which one is an update and call the according callback + } + ms_list_free(vCards); + linphone_carddav_sync_done(cdc, TRUE, ""); +} + +static MSList* parse_vcards_from_xml_response(const char *body) { + MSList *result = NULL; + xmlparsing_context_t *xml_ctx = linphone_xmlparsing_context_new(); + xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error); + xml_ctx->doc = xmlReadDoc((const unsigned char*)body, 0, NULL, 0); + if (xml_ctx->doc != NULL) { + if (linphone_create_xml_xpath_context(xml_ctx) < 0) goto end; + linphone_xml_xpath_context_init_carddav_ns(xml_ctx); + { + xmlXPathObjectPtr etags = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/d:multistatus/d:response/d:propstat/d:prop/d:getetag"); + xmlXPathObjectPtr hrefs = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/d:multistatus/d:response/d:href"); + xmlXPathObjectPtr vcards = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/d:multistatus/d:response/d:propstat/d:prop/card:address-data"); + if (etags != NULL && hrefs != NULL && vcards != NULL) { + if (etags->nodesetval != NULL && hrefs->nodesetval != NULL && vcards->nodesetval != NULL) { + xmlNodeSetPtr etags_nodes = etags->nodesetval; + xmlNodeSetPtr hrefs_nodes = hrefs->nodesetval; + xmlNodeSetPtr vcards_nodes = vcards->nodesetval; + if (etags_nodes->nodeNr >= 1 && hrefs_nodes->nodeNr == etags_nodes->nodeNr && vcards_nodes->nodeNr == etags_nodes->nodeNr) { + int i; + for (i = 0; i < vcards_nodes->nodeNr; i++) { + xmlNodePtr etag_node = etags_nodes->nodeTab[i]; + xmlNodePtr href_node = hrefs_nodes->nodeTab[i]; + xmlNodePtr vcard_node = vcards_nodes->nodeTab[i]; + if (vcard_node->children != NULL) { + char *etag = (char *)xmlNodeListGetString(xml_ctx->doc, etag_node->children, 1); + char *url = (char *)xmlNodeListGetString(xml_ctx->doc, href_node->children, 1); + char *vcard = (char *)xmlNodeListGetString(xml_ctx->doc, vcard_node->children, 1); + LinphoneCardDavResponse *response = ms_new0(LinphoneCardDavResponse, 1); + response->etag = ms_strdup(etag); + response->url = ms_strdup(url); + response->vcard = ms_strdup(vcard); + result = ms_list_append(result, response); + ms_debug("Added vCard object with eTag %s, URL %s and vCard %s", etag, url, vcard); + } + } + } + } + xmlXPathFreeObject(vcards); + xmlXPathFreeObject(etags); + xmlXPathFreeObject(hrefs); + } + } + } +end: + linphone_xmlparsing_context_destroy(xml_ctx); + return result; +} + +static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList *vCards) { + if (vCards != NULL && ms_list_size(vCards) > 0) { + //MSList *localFriends = linphone_core_fetch_friends_from_db(cdc->lc); + //TODO: call onDelete from the ones that are in localFriends but not in vCards + //TODO: remove from vCards the one that are in localFriends and for which the eTag hasn't changed + linphone_carddav_pull_vcards(cdc, vCards); + } + ms_list_free(vCards); +} + +static MSList* parse_vcards_etags_from_xml_response(const char *body) { + MSList *result = NULL; + xmlparsing_context_t *xml_ctx = linphone_xmlparsing_context_new(); + xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error); + xml_ctx->doc = xmlReadDoc((const unsigned char*)body, 0, NULL, 0); + if (xml_ctx->doc != NULL) { + if (linphone_create_xml_xpath_context(xml_ctx) < 0) goto end; + linphone_xml_xpath_context_init_carddav_ns(xml_ctx); + { + xmlXPathObjectPtr etags = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/d:multistatus/d:response/d:propstat/d:prop/d:getetag"); + xmlXPathObjectPtr hrefs = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/d:multistatus/d:response/d:href"); + if (etags != NULL && hrefs != NULL) { + if (etags->nodesetval != NULL && hrefs->nodesetval != NULL) { + xmlNodeSetPtr etags_nodes = etags->nodesetval; + xmlNodeSetPtr hrefs_nodes = hrefs->nodesetval; + if (etags_nodes->nodeNr >= 1 && hrefs_nodes->nodeNr == etags_nodes->nodeNr) { + int i; + for (i = 0; i < etags_nodes->nodeNr; i++) { + xmlNodePtr etag_node = etags_nodes->nodeTab[i]; + xmlNodePtr href_node = hrefs_nodes->nodeTab[i]; + if (etag_node->children != NULL && href_node->children != NULL) { + char *etag = (char *)xmlNodeListGetString(xml_ctx->doc, etag_node->children, 1); + char *url = (char *)xmlNodeListGetString(xml_ctx->doc, href_node->children, 1); + LinphoneCardDavResponse *response = ms_new0(LinphoneCardDavResponse, 1); + response->etag = ms_strdup(etag); + response->url = ms_strdup(url); + result = ms_list_append(result, response); + ms_debug("Added vCard object with eTag %s and URL %s", etag, url); + } + } + } + } + xmlXPathFreeObject(etags); + xmlXPathFreeObject(hrefs); + } + } + } +end: + linphone_xmlparsing_context_destroy(xml_ctx); + return result; +} + static void linphone_carddav_ctag_fetched(LinphoneCardDavContext *cdc, int ctag) { + ms_debug("Remote cTag for CardDAV addressbook is %i, local one is %i", ctag, cdc->ctag); if (ctag == -1 || ctag > cdc->ctag) { cdc->ctag = ctag; linphone_carddav_fetch_vcards(cdc); } else { ms_message("No changes found on server, skipping sync"); - if (cdc->sync_done_cb) { - cdc->sync_done_cb(cdc, TRUE, "Synchronization skipped because cTag already up to date"); - } + linphone_carddav_sync_done(cdc, TRUE, "Synchronization skipped because cTag already up to date"); } } -void linphone_carddav_synchronize(LinphoneCardDavContext *cdc) { - linphone_carddav_get_current_ctag(cdc); +static int parse_ctag_value_from_xml_response(const char *body) { + int result = -1; + xmlparsing_context_t *xml_ctx = linphone_xmlparsing_context_new(); + xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error); + xml_ctx->doc = xmlReadDoc((const unsigned char*)body, 0, NULL, 0); + if (xml_ctx->doc != NULL) { + char *response = NULL; + if (linphone_create_xml_xpath_context(xml_ctx) < 0) goto end; + linphone_xml_xpath_context_init_carddav_ns(xml_ctx); + response = linphone_get_xml_text_content(xml_ctx, "/d:multistatus/d:response/d:propstat/d:prop/x1:getctag"); + if (response) { + result = atoi(response); + linphone_free_xml_text_content(response); + } + } +end: + linphone_xmlparsing_context_destroy(xml_ctx); + return result; } static void process_response_from_carddav_request(void *data, const belle_http_response_event_t *event) { @@ -88,16 +215,16 @@ static void process_response_from_carddav_request(void *data, const belle_http_r int code = belle_http_response_get_status_code(event->response); if (code == 207 || code == 200) { const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response); - ms_message("CardDAV query response body: %s", body); query->status = LinphoneCardDavQueryStatusOk; switch(query->type) { case LinphoneCardDavQueryTypePropfind: - linphone_carddav_ctag_fetched(query->context, 0);//TODO parse value from body + linphone_carddav_ctag_fetched(query->context, parse_ctag_value_from_xml_response(body)); break; case LinphoneCardDavQueryTypeAddressbookQuery: - linphone_carddav_vcards_fetched(query->context, NULL);//TODO parse value from body + linphone_carddav_vcards_fetched(query->context, parse_vcards_etags_from_xml_response(body)); break; case LinphoneCardDavQueryTypeAddressbookMultiget: + linphone_carddav_vcards_pulled(query->context, parse_vcards_from_xml_response(body)); break; } } else { @@ -109,12 +236,10 @@ static void process_response_from_carddav_request(void *data, const belle_http_r static void process_io_error_from_carddav_request(void *data, const belle_sip_io_error_event_t *event) { LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data; - ms_error("I/O Error during CardDAV request sending"); + ms_error("I/O error during CardDAV request sending"); query->status = LinphoneCardDavQueryStatusFailed; ms_free(query); - if (query->context->sync_done_cb) { - query->context->sync_done_cb(query->context, FALSE, "I/O Error during CardDAV request sending"); - } + linphone_carddav_sync_done(query->context, FALSE, "I/O error during CardDAV request sending"); } static void process_auth_requested_from_carddav_request(void *data, belle_sip_auth_event_t *event) { @@ -131,10 +256,8 @@ static void process_auth_requested_from_carddav_request(void *data, belle_sip_au } } else { query->status = LinphoneCardDavQueryStatusFailed; - ms_error("Authentication error during CardDAV request sending"); - if (query->context->sync_done_cb) { - query->context->sync_done_cb(query->context, FALSE, "Authentication error during CardDAV request sending"); - } + ms_error("Authentication requested during CardDAV request sending, and username/password weren't provided"); + linphone_carddav_sync_done(query->context, FALSE, "Authentication requested during CardDAV request sending, and username/password weren't provided"); } } @@ -203,7 +326,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_addressbook_query(LinphoneC LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); query->context = cdc; query->depth = "1"; - query->body = ""; + query->body = ""; query->method = "REPORT"; query->url = cdc->server_url; query->type = LinphoneCardDavQueryTypeAddressbookQuery; @@ -218,13 +341,27 @@ void linphone_carddav_fetch_vcards(LinphoneCardDavContext *cdc) { static LinphoneCardDavQuery* linphone_carddav_create_addressbook_multiget_query(LinphoneCardDavContext *cdc, MSList *vcards) { LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); + char body[(ms_list_size(vcards)+1)*100]; + MSList *iterator = vcards; + query->context = cdc; query->depth = "1"; query->method = "REPORT"; query->url = cdc->server_url; query->type = LinphoneCardDavQueryTypeAddressbookMultiget; query->status = LinphoneCardDavQueryStatusIdle; - //TODO: body + + sprintf(body, "%s", ""); + while (iterator) { + LinphoneCardDavResponse *response = (LinphoneCardDavResponse *)iterator->data; + char temp_body[100]; + sprintf(temp_body, "%s", response->url); + sprintf(body, "%s%s", body, temp_body); + iterator = ms_list_next(iterator); + } + sprintf(body, "%s%s", body, ""); + query->body = ms_strdup(body); + return query; } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 3a306ad78..2baee1e21 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -7511,7 +7511,7 @@ void linphone_core_set_carddav_current_ctag(LinphoneCore *lc, int ctag) { int linphone_core_get_carddav_last_ctag(LinphoneCore *lc) { if (lc) { LpConfig *lpc = linphone_core_get_config(lc); - return lp_config_get_int(lpc, "carddav", "ctag", -1); + return lp_config_get_int(lpc, "carddav", "ctag", 0); } - return -1; + return 0; } \ No newline at end of file diff --git a/coreapi/private.h b/coreapi/private.h index f3c21934d..4197bcba8 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1328,6 +1328,7 @@ char * linphone_get_xml_text_content(xmlparsing_context_t *xml_ctx, const char * const char * linphone_get_xml_attribute_text_content(xmlparsing_context_t *xml_ctx, const char *xpath_expression, const char *attribute_name); void linphone_free_xml_text_content(const char *text); xmlXPathObjectPtr linphone_get_xml_xpath_object_for_node_list(xmlparsing_context_t *xml_ctx, const char *xpath_expression); +void linphone_xml_xpath_context_init_carddav_ns(xmlparsing_context_t *xml_ctx); /***************************************************************************** * OTHER UTILITY FUNCTIONS * diff --git a/coreapi/xml.c b/coreapi/xml.c index 28d773add..0b4e29077 100644 --- a/coreapi/xml.c +++ b/coreapi/xml.c @@ -123,3 +123,11 @@ void linphone_free_xml_text_content(const char *text) { xmlXPathObjectPtr linphone_get_xml_xpath_object_for_node_list(xmlparsing_context_t *xml_ctx, const char *xpath_expression) { return xmlXPathEvalExpression((const xmlChar *)xpath_expression, xml_ctx->xpath_ctx); } + +void linphone_xml_xpath_context_init_carddav_ns(xmlparsing_context_t *xml_ctx) { + if (xml_ctx && xml_ctx->xpath_ctx) { + xmlXPathRegisterNs(xml_ctx->xpath_ctx, (const xmlChar*)"d", (const xmlChar*)"DAV:"); + xmlXPathRegisterNs(xml_ctx->xpath_ctx, (const xmlChar*)"card", (const xmlChar*)"urn:ietf:params:xml:ns:carddav"); + xmlXPathRegisterNs(xml_ctx->xpath_ctx, (const xmlChar*)"x1", (const xmlChar*)"http://calendarserver.org/ns/"); + } +} \ No newline at end of file From 6fc86237ac78d2639346d32d382f3338af1c926a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 7 Jan 2016 14:24:40 +0100 Subject: [PATCH 046/121] Improve xml parsing of carddav responses --- coreapi/carddav.c | 86 ++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 50 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index f1a63d073..812d18139 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -86,37 +86,28 @@ static MSList* parse_vcards_from_xml_response(const char *body) { if (linphone_create_xml_xpath_context(xml_ctx) < 0) goto end; linphone_xml_xpath_context_init_carddav_ns(xml_ctx); { - xmlXPathObjectPtr etags = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/d:multistatus/d:response/d:propstat/d:prop/d:getetag"); - xmlXPathObjectPtr hrefs = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/d:multistatus/d:response/d:href"); - xmlXPathObjectPtr vcards = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/d:multistatus/d:response/d:propstat/d:prop/card:address-data"); - if (etags != NULL && hrefs != NULL && vcards != NULL) { - if (etags->nodesetval != NULL && hrefs->nodesetval != NULL && vcards->nodesetval != NULL) { - xmlNodeSetPtr etags_nodes = etags->nodesetval; - xmlNodeSetPtr hrefs_nodes = hrefs->nodesetval; - xmlNodeSetPtr vcards_nodes = vcards->nodesetval; - if (etags_nodes->nodeNr >= 1 && hrefs_nodes->nodeNr == etags_nodes->nodeNr && vcards_nodes->nodeNr == etags_nodes->nodeNr) { - int i; - for (i = 0; i < vcards_nodes->nodeNr; i++) { - xmlNodePtr etag_node = etags_nodes->nodeTab[i]; - xmlNodePtr href_node = hrefs_nodes->nodeTab[i]; - xmlNodePtr vcard_node = vcards_nodes->nodeTab[i]; - if (vcard_node->children != NULL) { - char *etag = (char *)xmlNodeListGetString(xml_ctx->doc, etag_node->children, 1); - char *url = (char *)xmlNodeListGetString(xml_ctx->doc, href_node->children, 1); - char *vcard = (char *)xmlNodeListGetString(xml_ctx->doc, vcard_node->children, 1); - LinphoneCardDavResponse *response = ms_new0(LinphoneCardDavResponse, 1); - response->etag = ms_strdup(etag); - response->url = ms_strdup(url); - response->vcard = ms_strdup(vcard); - result = ms_list_append(result, response); - ms_debug("Added vCard object with eTag %s, URL %s and vCard %s", etag, url, vcard); - } + xmlXPathObjectPtr responses = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/d:multistatus/d:response"); + if (responses != NULL && responses->nodesetval != NULL) { + xmlNodeSetPtr responses_nodes = responses->nodesetval; + if (responses_nodes->nodeNr >= 1) { + int i; + for (i = 0; i < responses_nodes->nodeNr; i++) { + xmlNodePtr response_node = responses_nodes->nodeTab[i]; + xml_ctx->xpath_ctx->node = response_node; + { + char *etag = linphone_get_xml_text_content(xml_ctx, "d:propstat/d:prop/d:getetag"); + char *url = linphone_get_xml_text_content(xml_ctx, "d:href"); + char *vcard = linphone_get_xml_text_content(xml_ctx, "d:propstat/d:prop/card:address-data"); + LinphoneCardDavResponse *response = ms_new0(LinphoneCardDavResponse, 1); + response->etag = ms_strdup(etag); + response->url = ms_strdup(url); + response->vcard = ms_strdup(vcard); + result = ms_list_append(result, response); + ms_debug("Added vCard object with eTag %s, URL %s and vCard %s", etag, url, vcard); } } } - xmlXPathFreeObject(vcards); - xmlXPathFreeObject(etags); - xmlXPathFreeObject(hrefs); + xmlXPathFreeObject(responses); } } } @@ -144,31 +135,26 @@ static MSList* parse_vcards_etags_from_xml_response(const char *body) { if (linphone_create_xml_xpath_context(xml_ctx) < 0) goto end; linphone_xml_xpath_context_init_carddav_ns(xml_ctx); { - xmlXPathObjectPtr etags = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/d:multistatus/d:response/d:propstat/d:prop/d:getetag"); - xmlXPathObjectPtr hrefs = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/d:multistatus/d:response/d:href"); - if (etags != NULL && hrefs != NULL) { - if (etags->nodesetval != NULL && hrefs->nodesetval != NULL) { - xmlNodeSetPtr etags_nodes = etags->nodesetval; - xmlNodeSetPtr hrefs_nodes = hrefs->nodesetval; - if (etags_nodes->nodeNr >= 1 && hrefs_nodes->nodeNr == etags_nodes->nodeNr) { - int i; - for (i = 0; i < etags_nodes->nodeNr; i++) { - xmlNodePtr etag_node = etags_nodes->nodeTab[i]; - xmlNodePtr href_node = hrefs_nodes->nodeTab[i]; - if (etag_node->children != NULL && href_node->children != NULL) { - char *etag = (char *)xmlNodeListGetString(xml_ctx->doc, etag_node->children, 1); - char *url = (char *)xmlNodeListGetString(xml_ctx->doc, href_node->children, 1); - LinphoneCardDavResponse *response = ms_new0(LinphoneCardDavResponse, 1); - response->etag = ms_strdup(etag); - response->url = ms_strdup(url); - result = ms_list_append(result, response); - ms_debug("Added vCard object with eTag %s and URL %s", etag, url); - } + xmlXPathObjectPtr responses = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/d:multistatus/d:response"); + if (responses != NULL && responses->nodesetval != NULL) { + xmlNodeSetPtr responses_nodes = responses->nodesetval; + if (responses_nodes->nodeNr >= 1) { + int i; + for (i = 0; i < responses_nodes->nodeNr; i++) { + xmlNodePtr response_node = responses_nodes->nodeTab[i]; + xml_ctx->xpath_ctx->node = response_node; + { + char *etag = linphone_get_xml_text_content(xml_ctx, "d:propstat/d:prop/d:getetag"); + char *url = linphone_get_xml_text_content(xml_ctx, "d:href"); + LinphoneCardDavResponse *response = ms_new0(LinphoneCardDavResponse, 1); + response->etag = ms_strdup(etag); + response->url = ms_strdup(url); + result = ms_list_append(result, response); + ms_debug("Added vCard object with eTag %s and URL %s", etag, url); } } } - xmlXPathFreeObject(etags); - xmlXPathFreeObject(hrefs); + xmlXPathFreeObject(responses); } } } From 873493b62832293da85c3fa5e18d44c660b1d8ca Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 7 Jan 2016 15:44:59 +0100 Subject: [PATCH 047/121] More work on CardDAV sync: store etag and url for each vcard in db, call the correct callbacks and improved tester using stats --- coreapi/carddav.c | 92 +++++++++++++++++++++++++++++++++++++++---- coreapi/carddav.h | 27 +++++++++++-- coreapi/friend.c | 30 ++++++++++---- coreapi/vcard.cc | 25 ++++++++++++ coreapi/vcard.h | 8 ++++ coreapi/vcard_stubs.c | 20 ++++++++++ tester/vcard_tester.c | 42 +++++++++++++++++++- 7 files changed, 223 insertions(+), 21 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 812d18139..13554178a 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -61,7 +61,10 @@ void linphone_carddav_synchronize(LinphoneCardDavContext *cdc) { static void linphone_carddav_sync_done(LinphoneCardDavContext *cdc, bool_t success, const char *msg) { if (success) { + ms_debug("CardDAV sync successful, saving new cTag: %i", cdc->ctag); linphone_core_set_carddav_current_ctag(cdc->lc, cdc->ctag); + } else { + ms_error("CardDAV sync failure: %s", msg); } if (cdc->sync_done_cb) { @@ -69,9 +72,37 @@ static void linphone_carddav_sync_done(LinphoneCardDavContext *cdc, bool_t succe } } +static int find_matching_friend(LinphoneFriend *lf1, LinphoneFriend *lf2) { + LinphoneVCard *lvc1 = linphone_friend_get_vcard(lf1); + LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf2); + return strcmp(linphone_vcard_get_uid(lvc1), linphone_vcard_get_uid(lvc2)); +} + static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList *vCards) { if (vCards != NULL && ms_list_size(vCards) > 0) { - //TODO: find out which one is new and which one is an update and call the according callback + MSList *localFriends = linphone_core_fetch_friends_from_db(cdc->lc); + while (vCards) { + LinphoneCardDavResponse *vCard = (LinphoneCardDavResponse *)vCards->data; + if (vCard) { + LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer(vCard->vcard); + LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); + MSList *local_friend = ms_list_find_custom(localFriends, (int (*)(const void*, const void*))find_matching_friend, lf); + if (local_friend) { + LinphoneFriend *lf2 = (LinphoneFriend *)local_friend->data; + if (cdc->contact_updated_cb) { + ms_debug("Contact updated: %s", linphone_friend_get_name(lf)); + cdc->contact_updated_cb(cdc, lf, lf2); + } + } else { + if (cdc->contact_created_cb) { + ms_debug("Contact created: %s", linphone_friend_get_name(lf)); + cdc->contact_created_cb(cdc, lf); + } + } + } + vCards = ms_list_next(vCards); + } + ms_list_free(localFriends); } ms_list_free(vCards); linphone_carddav_sync_done(cdc, TRUE, ""); @@ -116,11 +147,42 @@ end: return result; } +static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend *lf) { + LinphoneVCard *lvc1 = linphone_vcard_new_from_vcard4_buffer(response->vcard); + LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf); + return strcmp(linphone_vcard_get_uid(lvc1), linphone_vcard_get_uid(lvc2)); +} + static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList *vCards) { if (vCards != NULL && ms_list_size(vCards) > 0) { - //MSList *localFriends = linphone_core_fetch_friends_from_db(cdc->lc); - //TODO: call onDelete from the ones that are in localFriends but not in vCards - //TODO: remove from vCards the one that are in localFriends and for which the eTag hasn't changed + MSList *localFriends = linphone_core_fetch_friends_from_db(cdc->lc); + MSList *friends = localFriends; + while (friends) { + LinphoneFriend *lf = (LinphoneFriend *)friends->data; + if (lf) { + MSList *vCard = ms_list_find_custom(vCards, (int (*)(const void*, const void*))find_matching_vcard, lf); + if (!vCard) { + ms_debug("Local friend %s isn't in the remote vCard list, delete it", linphone_friend_get_name(lf)); + if (cdc->contact_removed_cb) { + lf = linphone_friend_ref(lf); + ms_debug("Contact removed: %s", linphone_friend_get_name(lf)); + cdc->contact_removed_cb(cdc, lf); + } + } else { + LinphoneCardDavResponse *response = (LinphoneCardDavResponse *)vCard->data; + ms_debug("Local friend %s is in the remote vCard list, check eTag", linphone_friend_get_name(lf)); + if (response) { + LinphoneVCard *lvc = linphone_friend_get_vcard(lf); + ms_debug("Local friend eTag is %s, remote vCard eTag is %s", linphone_vcard_get_etag(lvc), response->etag); + if (lvc && strcmp(linphone_vcard_get_etag(lvc), response->etag) == 0) { + ms_list_remove(vCards, vCard); + } + } + } + } + friends = ms_list_next(friends); + } + ms_list_free(localFriends); linphone_carddav_pull_vcards(cdc, vCards); } ms_list_free(vCards); @@ -291,6 +353,18 @@ void linphone_carddav_set_synchronization_done_callback(LinphoneCardDavContext * cdc->sync_done_cb = cb; } +void linphone_carddav_set_new_contact_callback(LinphoneCardDavContext *cdc, LinphoneCardDavContactCreatedCb cb) { + cdc->contact_created_cb = cb; +} + +void linphone_carddav_set_updated_contact_callback(LinphoneCardDavContext *cdc, LinphoneCardDavContactUpdatedCb cb) { + cdc->contact_updated_cb = cb; +} + +void linphone_carddav_set_removed_contact_callback(LinphoneCardDavContext *cdc, LinphoneCardDavContactRemovedCb cb) { + cdc->contact_removed_cb = cb; +} + static LinphoneCardDavQuery* linphone_carddav_create_propfind_query(LinphoneCardDavContext *cdc) { LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); query->context = cdc; @@ -340,10 +414,12 @@ static LinphoneCardDavQuery* linphone_carddav_create_addressbook_multiget_query( sprintf(body, "%s", ""); while (iterator) { LinphoneCardDavResponse *response = (LinphoneCardDavResponse *)iterator->data; - char temp_body[100]; - sprintf(temp_body, "%s", response->url); - sprintf(body, "%s%s", body, temp_body); - iterator = ms_list_next(iterator); + if (response) { + char temp_body[100]; + sprintf(temp_body, "%s", response->url); + sprintf(body, "%s%s", body, temp_body); + iterator = ms_list_next(iterator); + } } sprintf(body, "%s%s", body, ""); query->body = ms_strdup(body); diff --git a/coreapi/carddav.h b/coreapi/carddav.h index 8cb4b5bc1..1a8a22b26 100644 --- a/coreapi/carddav.h +++ b/coreapi/carddav.h @@ -46,17 +46,17 @@ typedef struct _LinphoneCardDavResponse LinphoneCardDavResponse; /** * Callback used to notify a new contact has been created on the CardDAV server **/ -typedef void (*LinphoneCardDavContactCreatedCb)(LinphoneFriend *lf); +typedef void (*LinphoneCardDavContactCreatedCb)(LinphoneCardDavContext *cdc, LinphoneFriend *lf); /** * Callback used to notify a contact has been updated on the CardDAV server **/ -typedef void (*LinphoneCardDavContactUpdatedCb)(LinphoneFriend *lf); +typedef void (*LinphoneCardDavContactUpdatedCb)(LinphoneCardDavContext *cdc, LinphoneFriend *new_friend, LinphoneFriend *old_friend); /** * Callback used to notify a contact has been removed on the CardDAV server **/ -typedef void (*LinphoneCardDavContactRemovedCb)(LinphoneFriend *lf); +typedef void (*LinphoneCardDavContactRemovedCb)(LinphoneCardDavContext *cdc, LinphoneFriend *lf); /** * Callback used to notify a contact has been removed on the CardDAV server @@ -117,6 +117,27 @@ LINPHONE_PUBLIC void linphone_carddav_delete_vcard(LinphoneCardDavContext *cdc, */ LINPHONE_PUBLIC void linphone_carddav_set_synchronization_done_callback(LinphoneCardDavContext *cdc, LinphoneCardDavSynchronizationDoneCb cb); +/** + * Set the new contact callback. + * @param cdc LinphoneCardDavContext object + * @param cb The new contact callback to be used. + */ +LINPHONE_PUBLIC void linphone_carddav_set_new_contact_callback(LinphoneCardDavContext *cdc, LinphoneCardDavContactCreatedCb cb); + +/** + * Set the updated contact callback. + * @param cdc LinphoneCardDavContext object + * @param cb The updated contact callback to be used. + */ +LINPHONE_PUBLIC void linphone_carddav_set_updated_contact_callback(LinphoneCardDavContext *cdc, LinphoneCardDavContactUpdatedCb cb); + +/** + * Set the removed contact callback. + * @param cdc LinphoneCardDavContext object + * @param cb The removed contact callback to be used. + */ +LINPHONE_PUBLIC void linphone_carddav_set_removed_contact_callback(LinphoneCardDavContext *cdc, LinphoneCardDavContactRemovedCb cb); + /** * Retrieves the current cTag value for the remote server * @param cdc LinphoneCardDavContext object diff --git a/coreapi/friend.c b/coreapi/friend.c index afb07f711..5baf9393c 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -935,6 +935,8 @@ static void linphone_create_table(sqlite3* db) { "send_subscribe INTEGER," "ref_key TEXT," "vCard TEXT," + "vCard_etag TEXT," + "vCard_url TEXT," "presence_received INTEGER" ");", 0, 0, &errmsg); @@ -992,7 +994,9 @@ void linphone_core_friends_storage_close(LinphoneCore *lc) { * | 3 | send_subscribe * | 4 | ref_key * | 5 | vCard - * | 6 | presence_received + * | 6 | vCard eTag + * | 7 | vCard URL + * | 8 | presence_received */ static int create_friend(void *data, int argc, char **argv, char **colName) { MSList **list = (MSList **)data; @@ -1001,7 +1005,11 @@ static int create_friend(void *data, int argc, char **argv, char **colName) { unsigned int storage_id = atoi(argv[0]); vcard = linphone_vcard_new_from_vcard4_buffer(argv[5]); - lf = linphone_friend_new_from_vcard(vcard); + if (vcard) { + linphone_vcard_set_etag(vcard, argv[6]); + linphone_vcard_set_url(vcard, argv[7]); + lf = linphone_friend_new_from_vcard(vcard); + } if (!lf) { LinphoneAddress *addr = linphone_address_new(argv[1]); lf = linphone_friend_new(); @@ -1009,8 +1017,8 @@ static int create_friend(void *data, int argc, char **argv, char **colName) { } linphone_friend_set_inc_subscribe_policy(lf, atoi(argv[2])); linphone_friend_send_subscribe(lf, atoi(argv[3])); - linphone_friend_set_ref_key(lf, argv[4]); - lf->presence_received = atoi(argv[6]); + linphone_friend_set_ref_key(lf, ms_strdup(argv[4])); + lf->presence_received = atoi(argv[8]); lf->storage_id = storage_id; *list = ms_list_append(*list, linphone_friend_ref(lf)); @@ -1044,27 +1052,33 @@ void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) { if (lc && lc->friends_db) { char *buf; int store_friends = lp_config_get_int(lc->config, "misc", "store_friends", 1); + LinphoneVCard *vcard = linphone_friend_get_vcard(lf); + if (!store_friends) { return; } if (lf->storage_id > 0) { - buf = sqlite3_mprintf("UPDATE friends SET sip_uri=%Q,subscribe_policy=%i,send_subscribe=%i,ref_key=%Q,vCard=%Q,presence_received=%i WHERE (id = %i);", + buf = sqlite3_mprintf("UPDATE friends SET sip_uri=%Q,subscribe_policy=%i,send_subscribe=%i,ref_key=%Q,vCard=%Q,vCard_etag=%Q,vCard_url=%Q,presence_received=%i WHERE (id = %i);", linphone_address_as_string(linphone_friend_get_address(lf)), lf->pol, lf->subscribe, lf->refkey, - linphone_vcard_as_vcard4_string(linphone_friend_get_vcard(lf)), + linphone_vcard_as_vcard4_string(vcard), + linphone_vcard_get_etag(vcard), + linphone_vcard_get_url(vcard), lf->presence_received, lf->storage_id ); } else { - buf = sqlite3_mprintf("INSERT INTO friends VALUES(NULL,%Q,%i,%i,%Q,%Q,%i);", + buf = sqlite3_mprintf("INSERT INTO friends VALUES(NULL,%Q,%i,%i,%Q,%Q,%Q,%Q,%i);", linphone_address_as_string(linphone_friend_get_address(lf)), lf->pol, lf->subscribe, lf->refkey, - linphone_vcard_as_vcard4_string(linphone_friend_get_vcard(lf)), + linphone_vcard_as_vcard4_string(vcard), + linphone_vcard_get_etag(vcard), + linphone_vcard_get_url(vcard), lf->presence_received ); } diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 0ecff260c..039ec200f 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -23,6 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. struct _LinphoneVCard { shared_ptr belCard; + const char *etag; + const char *url; }; extern "C" LinphoneVCard* linphone_vcard_new(void) { @@ -150,4 +152,27 @@ extern "C" MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) } } return result; +} + +extern "C" const char* linphone_vcard_get_uid(const LinphoneVCard *vCard) { + if (vCard->belCard->getUniqueId()) { + return vCard->belCard->getUniqueId()->getValue().c_str(); + } + return NULL; +} + +extern "C" void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag) { + vCard->etag = ms_strdup(etag); +} + +extern "C" const char* linphone_vcard_get_etag(const LinphoneVCard *vCard) { + return vCard->etag; +} + +extern "C" void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url) { + vCard->url = ms_strdup(url); +} + +extern "C" const char* linphone_vcard_get_url(const LinphoneVCard *vCard) { + return vCard->url; } \ No newline at end of file diff --git a/coreapi/vcard.h b/coreapi/vcard.h index 4ad094915..c8eeec45d 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -119,6 +119,14 @@ LINPHONE_PUBLIC void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, */ LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard); +const char* linphone_vcard_get_uid(const LinphoneVCard *vCard); + +void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag); +const char* linphone_vcard_get_etag(const LinphoneVCard *vCard); + +void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url); +const char* linphone_vcard_get_url(const LinphoneVCard *vCard); + /** * @} */ diff --git a/coreapi/vcard_stubs.c b/coreapi/vcard_stubs.c index d50ab29b9..148858e09 100644 --- a/coreapi/vcard_stubs.c +++ b/coreapi/vcard_stubs.c @@ -69,4 +69,24 @@ void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const char *sip_ MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) { return NULL; +} + +const char* linphone_vcard_get_uid(const LinphoneVCard *vCard) { + return NULL; +} + +void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag) { + +} + +const char* linphone_vcard_get_etag(const LinphoneVCard *vCard) { + return NULL; +} + +void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url) { + +} + +const char* linphone_vcard_get_url(const LinphoneVCard *vCard) { + return NULL; } \ No newline at end of file diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 7a1506cf1..f6531eb40 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -184,24 +184,62 @@ end: } #endif +typedef struct _LinphoneCardDAVStats { + int sync_done_count; + int new_contact_count; + int removed_contact_count; + int updated_contact_count; +} LinphoneCardDAVStats; + static void carddav_sync_done(LinphoneCardDavContext *c, bool_t success, const char *message) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_TRUE(success); + stats->sync_done_count++; linphone_carddav_destroy(c); } +static void carddav_new_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); + BC_ASSERT_PTR_NOT_NULL_FATAL(lf); + stats->new_contact_count++; + linphone_friend_unref(lf); +} + +static void carddav_removed_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); + BC_ASSERT_PTR_NOT_NULL_FATAL(lf); + stats->removed_contact_count++; + linphone_friend_unref(lf); +} + +static void carddav_updated_contact(LinphoneCardDavContext *c, LinphoneFriend *lf1, LinphoneFriend *lf2) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); + BC_ASSERT_PTR_NOT_NULL_FATAL(lf1); + BC_ASSERT_PTR_NOT_NULL_FATAL(lf2); + stats->updated_contact_count++; + linphone_friend_unref(lf1); + linphone_friend_unref(lf2); +} + static void carddav_sync(void) { LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); BC_ASSERT_PTR_NOT_NULL_FATAL(c); BC_ASSERT_PTR_NOT_NULL(c->server_url); BC_ASSERT_PTR_NOT_NULL(c->username); BC_ASSERT_PTR_NOT_NULL(c->ha1); + linphone_carddav_set_user_data(c, stats); linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); + linphone_carddav_set_new_contact_callback(c, carddav_new_contact); + linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact); + linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact); linphone_carddav_synchronize(c); - wait_for_until(manager->lc, NULL, NULL, 1, 1000); + wait_for_until(manager->lc, NULL, &stats->new_contact_count, 1, 2000); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); linphone_core_manager_destroy(manager); } #else @@ -219,7 +257,7 @@ test_t vcard_tests[] = { { "Friends storage migration from rc to db", friends_migration }, { "Friends storage in sqlite database", friends_sqlite_storage }, #endif - { "CardDAV synchronization", carddav_sync } + { "CardDAV synchronization", carddav_sync }, #else { "Dummy test", dummy_test } #endif From 5ff8d1232f4fbdfff0ecc768b073ee0259f4b20f Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 7 Jan 2016 16:36:52 +0100 Subject: [PATCH 048/121] Fixed carddav tests --- coreapi/carddav.c | 14 +++++++-- coreapi/vcard.cc | 6 +++- tester/vcard_tester.c | 72 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 3 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 13554178a..9ad732b87 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -75,7 +75,12 @@ static void linphone_carddav_sync_done(LinphoneCardDavContext *cdc, bool_t succe static int find_matching_friend(LinphoneFriend *lf1, LinphoneFriend *lf2) { LinphoneVCard *lvc1 = linphone_friend_get_vcard(lf1); LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf2); - return strcmp(linphone_vcard_get_uid(lvc1), linphone_vcard_get_uid(lvc2)); + const char *uid1 = linphone_vcard_get_uid(lvc1); + const char *uid2 = linphone_vcard_get_uid(lvc2); + if (!uid1 || !uid2) { + return 1; + } + return strcmp(uid1, uid2); } static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList *vCards) { @@ -150,7 +155,12 @@ end: static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend *lf) { LinphoneVCard *lvc1 = linphone_vcard_new_from_vcard4_buffer(response->vcard); LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf); - return strcmp(linphone_vcard_get_uid(lvc1), linphone_vcard_get_uid(lvc2)); + const char *uid1 = linphone_vcard_get_uid(lvc1); + const char *uid2 = linphone_vcard_get_uid(lvc2); + if (!uid1 || !uid2) { + return 1; + } + return strcmp(uid1, uid2); } static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList *vCards) { diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 039ec200f..c8d94c5b2 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -82,6 +82,8 @@ extern "C" LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buff if (belCard) { vCard = linphone_vcard_new(); vCard->belCard = belCard; + } else { + ms_error("Couldn't parse buffer %s", buffer); } } return vCard; @@ -155,7 +157,7 @@ extern "C" MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) } extern "C" const char* linphone_vcard_get_uid(const LinphoneVCard *vCard) { - if (vCard->belCard->getUniqueId()) { + if (vCard && vCard->belCard->getUniqueId()) { return vCard->belCard->getUniqueId()->getValue().c_str(); } return NULL; @@ -166,6 +168,7 @@ extern "C" void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag) } extern "C" const char* linphone_vcard_get_etag(const LinphoneVCard *vCard) { + if (!vCard) return NULL; return vCard->etag; } @@ -174,5 +177,6 @@ extern "C" void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url) { } extern "C" const char* linphone_vcard_get_url(const LinphoneVCard *vCard) { + if (!vCard) return NULL; return vCard->url; } \ No newline at end of file diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index f6531eb40..896a4c24d 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -239,9 +239,79 @@ static void carddav_sync(void) { linphone_carddav_synchronize(c); wait_for_until(manager->lc, NULL, &stats->new_contact_count, 1, 2000); + BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i"); wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); linphone_core_manager_destroy(manager); } + +static void carddav_sync_2(void) { + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); + LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + LinphoneFriend *lf = linphone_friend_new_with_address("\"Sylvain\" "); + char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); + + unlink(friends_db); + linphone_core_set_friends_database_path(manager->lc, friends_db); + linphone_core_add_friend(manager->lc, lf); + linphone_friend_unref(lf); + + BC_ASSERT_PTR_NOT_NULL_FATAL(c); + BC_ASSERT_PTR_NOT_NULL(c->server_url); + BC_ASSERT_PTR_NOT_NULL(c->username); + BC_ASSERT_PTR_NOT_NULL(c->ha1); + + linphone_carddav_set_user_data(c, stats); + linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); + linphone_carddav_set_new_contact_callback(c, carddav_new_contact); + linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact); + linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact); + + linphone_carddav_synchronize(c); + + wait_for_until(manager->lc, NULL, &stats->new_contact_count, 1, 2000); + BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->removed_contact_count, 1, 2000); + BC_ASSERT_EQUAL(stats->removed_contact_count, 1, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + linphone_core_manager_destroy(manager); +} + +static void carddav_sync_3(void) { + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); + LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nUID:79100a4d-2806-482f-bf27-0e09dc47149b\r\nFN:Sylvain Berfini\r\nIMPP;TYPE=work:sip:sylvain@sip.linphone.org\r\nEND:VCARD\r\n"); + LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); + char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); + + unlink(friends_db); + linphone_core_set_friends_database_path(manager->lc, friends_db); + linphone_core_add_friend(manager->lc, lf); + linphone_friend_unref(lf); + + BC_ASSERT_PTR_NOT_NULL_FATAL(c); + BC_ASSERT_PTR_NOT_NULL(c->server_url); + BC_ASSERT_PTR_NOT_NULL(c->username); + BC_ASSERT_PTR_NOT_NULL(c->ha1); + + linphone_carddav_set_user_data(c, stats); + linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); + linphone_carddav_set_new_contact_callback(c, carddav_new_contact); + linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact); + linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact); + + linphone_carddav_synchronize(c); + + wait_for_until(manager->lc, NULL, &stats->updated_contact_count, 1, 2000); + BC_ASSERT_EQUAL(stats->updated_contact_count, 1, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + linphone_core_manager_destroy(manager); +} + #else static void dummy_test(void) { @@ -258,6 +328,8 @@ test_t vcard_tests[] = { { "Friends storage in sqlite database", friends_sqlite_storage }, #endif { "CardDAV synchronization", carddav_sync }, + { "CardDAV synchronization 2", carddav_sync_2 }, + { "CardDAV synchronization 3", carddav_sync_3 }, #else { "Dummy test", dummy_test } #endif From 4561b0ce8cbf598f9a8baf2e2b7e1c6038a0a09b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 7 Jan 2016 17:04:29 +0100 Subject: [PATCH 049/121] Fixed a leak --- coreapi/carddav.c | 8 +++++--- tester/vcard_tester.c | 18 ++++++++++++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 9ad732b87..9fb79a58e 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -96,6 +96,7 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * LinphoneFriend *lf2 = (LinphoneFriend *)local_friend->data; if (cdc->contact_updated_cb) { ms_debug("Contact updated: %s", linphone_friend_get_name(lf)); + lf2 = linphone_friend_ref(lf2); cdc->contact_updated_cb(cdc, lf, lf2); } } else { @@ -107,7 +108,7 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * } vCards = ms_list_next(vCards); } - ms_list_free(localFriends); + localFriends = ms_list_free_with_data(localFriends, (void (*)(void *))linphone_friend_unref); } ms_list_free(vCards); linphone_carddav_sync_done(cdc, TRUE, ""); @@ -174,8 +175,8 @@ static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList if (!vCard) { ms_debug("Local friend %s isn't in the remote vCard list, delete it", linphone_friend_get_name(lf)); if (cdc->contact_removed_cb) { - lf = linphone_friend_ref(lf); ms_debug("Contact removed: %s", linphone_friend_get_name(lf)); + lf = linphone_friend_ref(lf); cdc->contact_removed_cb(cdc, lf); } } else { @@ -186,13 +187,14 @@ static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList ms_debug("Local friend eTag is %s, remote vCard eTag is %s", linphone_vcard_get_etag(lvc), response->etag); if (lvc && strcmp(linphone_vcard_get_etag(lvc), response->etag) == 0) { ms_list_remove(vCards, vCard); + ms_free(response); } } } } friends = ms_list_next(friends); } - ms_list_free(localFriends); + localFriends = ms_list_free_with_data(localFriends, (void (*)(void *))linphone_friend_unref); linphone_carddav_pull_vcards(cdc, vCards); } ms_list_free(vCards); diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 896a4c24d..4be0ecafb 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -194,31 +194,31 @@ typedef struct _LinphoneCardDAVStats { static void carddav_sync_done(LinphoneCardDavContext *c, bool_t success, const char *message) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_TRUE(success); - stats->sync_done_count++; linphone_carddav_destroy(c); + stats->sync_done_count++; } static void carddav_new_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_PTR_NOT_NULL_FATAL(lf); - stats->new_contact_count++; linphone_friend_unref(lf); + stats->new_contact_count++; } static void carddav_removed_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_PTR_NOT_NULL_FATAL(lf); - stats->removed_contact_count++; linphone_friend_unref(lf); + stats->removed_contact_count++; } static void carddav_updated_contact(LinphoneCardDavContext *c, LinphoneFriend *lf1, LinphoneFriend *lf2) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_PTR_NOT_NULL_FATAL(lf1); BC_ASSERT_PTR_NOT_NULL_FATAL(lf2); - stats->updated_contact_count++; linphone_friend_unref(lf1); linphone_friend_unref(lf2); + stats->updated_contact_count++; } static void carddav_sync(void) { @@ -242,6 +242,8 @@ static void carddav_sync(void) { BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i"); wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + + ms_free(stats); linphone_core_manager_destroy(manager); } @@ -276,6 +278,10 @@ static void carddav_sync_2(void) { BC_ASSERT_EQUAL(stats->removed_contact_count, 1, int, "%i"); wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + + ms_free(stats); + unlink(friends_db); + ms_free(friends_db); linphone_core_manager_destroy(manager); } @@ -309,6 +315,10 @@ static void carddav_sync_3(void) { BC_ASSERT_EQUAL(stats->updated_contact_count, 1, int, "%i"); wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + + ms_free(stats); + unlink(friends_db); + ms_free(friends_db); linphone_core_manager_destroy(manager); } From c72496a7e675f690726cd493a27fa3948d29812e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 8 Jan 2016 11:34:45 +0100 Subject: [PATCH 050/121] Fix autotools compilation --- coreapi/Makefile.am | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 9acf9dd27..96be8a14d 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -126,7 +126,7 @@ else liblinphone_la_SOURCES+=vcard_stubs.c vcard.h endif -liblinphone_la_LDFLAGS=-lstdc++ -version-info $(LIBLINPHONE_SO_VERSION) -no-undefined +liblinphone_la_LDFLAGS=-version-info $(LIBLINPHONE_SO_VERSION) -no-undefined if HAVE_LD_OUTPUT_DEF liblinphone_la_LDFLAGS += -Wl,--output-def,liblinphone-$(LIBLINPHONE_SO_CURRENT).def @@ -159,7 +159,8 @@ liblinphone_la_LIBADD= \ AM_CPPFLAGS=\ -I$(top_srcdir) -I$(top_srcdir)/include -I$(builddir) \ $(ORTP_CFLAGS) \ - $(MEDIASTREAMER_CFLAGS) + $(MEDIASTREAMER_CFLAGS) \ + $(LIBXML2_CFLAGS) COMMON_CFLAGS=\ $(STRICT_OPTIONS) \ From 8f493e0c1235bcbefb90b225e0e8e6974dd7e6d5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 8 Jan 2016 11:43:04 +0100 Subject: [PATCH 051/121] Test vcard' eTag and URL field storage in database --- tester/vcard_tester.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 4be0ecafb..c146ac7f7 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -124,6 +124,7 @@ end: static void friends_sqlite_storage(void) { LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneVCard *lvc = linphone_vcard_new(); LinphoneFriend *lf = linphone_friend_new(); LinphoneFriend *lf2 = NULL; LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); @@ -137,6 +138,9 @@ static void friends_sqlite_storage(void) { friends_from_db = linphone_core_fetch_friends_from_db(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); + linphone_vcard_set_etag(lvc, "\"123-456789\""); + linphone_vcard_set_url(lvc, "http://dav.somewhere.fr/addressbook/me/someone.vcf"); + linphone_friend_set_vcard(lf, lvc); linphone_friend_set_address(lf, addr); linphone_friend_set_name(lf, "Sylvain"); linphone_core_add_friend(manager->lc, lf); @@ -154,6 +158,8 @@ static void friends_sqlite_storage(void) { lf2 = (LinphoneFriend *)friends_from_db->data; BC_ASSERT_STRING_EQUAL(linphone_friend_get_name(lf2), linphone_friend_get_name(lf)); BC_ASSERT_EQUAL(lf2->storage_id, lf->storage_id, int, "%i"); + BC_ASSERT_STRING_EQUAL(linphone_vcard_get_etag(linphone_friend_get_vcard(lf2)), linphone_vcard_get_etag(linphone_friend_get_vcard(lf))); + BC_ASSERT_STRING_EQUAL(linphone_vcard_get_url(linphone_friend_get_vcard(lf2)), linphone_vcard_get_url(linphone_friend_get_vcard(lf))); BC_ASSERT_STRING_EQUAL(linphone_address_as_string(linphone_friend_get_address(lf2)), linphone_address_as_string(linphone_friend_get_address(lf))); linphone_friend_edit(lf); From e64884389095d852eb93b941053fdd9fee646155 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 8 Jan 2016 17:08:20 +0100 Subject: [PATCH 052/121] PUT/DELETE queries added to CardDAV (update not tested yet) --- coreapi/bellesip_sal/sal_impl.c | 14 ++- coreapi/carddav.c | 168 ++++++++++++++++++++++++++++---- coreapi/carddav.h | 20 ++-- coreapi/private.h | 3 +- coreapi/vcard.cc | 70 +++++++++---- coreapi/vcard.h | 44 ++++++++- coreapi/vcard_stubs.c | 8 ++ include/sal/sal.h | 1 + tester/vcard_tester.c | 38 +++++++- 9 files changed, 316 insertions(+), 50 deletions(-) diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index c98dbec7f..19fb28cea 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -976,12 +976,11 @@ typedef struct { unsigned char node[6]; } sal_uuid_t; - -int sal_create_uuid(Sal*ctx, char *uuid, size_t len){ +int sal_generate_uuid(char *uuid, size_t len) { sal_uuid_t uuid_struct; int i; int written; - + if (len==0) return -1; /*create an UUID as described in RFC4122, 4.4 */ belle_sip_random_bytes((unsigned char*)&uuid_struct, sizeof(sal_uuid_t)); @@ -1000,10 +999,17 @@ int sal_create_uuid(Sal*ctx, char *uuid, size_t len){ for (i = 0; i < 6; i++) written+=snprintf(uuid+written,len-written,"%2.2x", uuid_struct.node[i]); uuid[len-1]='\0'; - sal_set_uuid(ctx,uuid); return 0; } +int sal_create_uuid(Sal*ctx, char *uuid, size_t len) { + if (sal_generate_uuid(uuid, len) == 0) { + sal_set_uuid(ctx, uuid); + return 0; + } + return -1; +} + static void make_supported_header(Sal *sal){ MSList *it; char *alltags=NULL; diff --git a/coreapi/carddav.c b/coreapi/carddav.c index ea7b0b63b..f9ea99f73 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -274,9 +274,8 @@ static void process_response_from_carddav_request(void *data, const belle_http_r if (event->response) { int code = belle_http_response_get_status_code(event->response); - if (code == 207 || code == 200) { + if (code == 207 || code == 200 || code == 201 || code == 204) { const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response); - query->status = LinphoneCardDavQueryStatusOk; switch(query->type) { case LinphoneCardDavQueryTypePropfind: linphone_carddav_ctag_fetched(query->context, parse_ctag_value_from_xml_response(body)); @@ -287,10 +286,38 @@ static void process_response_from_carddav_request(void *data, const belle_http_r case LinphoneCardDavQueryTypeAddressbookMultiget: linphone_carddav_vcards_pulled(query->context, parse_vcards_from_xml_response(body)); break; + case LinphoneCardDavQueryTypePut: + { + belle_sip_header_t *header = belle_sip_message_get_header((belle_sip_message_t *)event->response, "ETag"); + LinphoneFriend *lf = (LinphoneFriend *)query->user_data; + if (lf) { + LinphoneVCard *lvc = linphone_friend_get_vcard(lf); + if (header && lvc && !linphone_vcard_get_etag(lvc)) { + const char *etag = belle_sip_header_get_unparsed_value(header); + ms_debug("eTag for newly created vCard is: %s", etag); + linphone_vcard_set_etag(lvc, etag); + } + linphone_carddav_sync_done(query->context, TRUE, ""); + linphone_friend_unref(lf); + } else { + linphone_carddav_sync_done(query->context, FALSE, "No LinphoneFriend found in user_date field of query"); + } + } + break; + case LinphoneCardDavQueryTypeDelete: + linphone_carddav_sync_done(query->context, TRUE, ""); + break; + default: + ms_error("Unknown request: %i", query->type); + break; } } else { - query->status = LinphoneCardDavQueryStatusFailed; + char msg[100]; + snprintf(msg, sizeof(msg), "Unexpected HTTP response code: %i", code); + linphone_carddav_sync_done(query->context, FALSE, msg); } + } else { + linphone_carddav_sync_done(query->context, FALSE, "No response found"); } ms_free(query); } @@ -298,7 +325,6 @@ static void process_response_from_carddav_request(void *data, const belle_http_r static void process_io_error_from_carddav_request(void *data, const belle_sip_io_error_event_t *event) { LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data; ms_error("I/O error during CardDAV request sending"); - query->status = LinphoneCardDavQueryStatusFailed; ms_free(query); linphone_carddav_sync_done(query->context, FALSE, "I/O error during CardDAV request sending"); } @@ -316,7 +342,6 @@ static void process_auth_requested_from_carddav_request(void *data, belle_sip_au belle_sip_auth_event_set_ha1(event, context->ha1); } } else { - query->status = LinphoneCardDavQueryStatusFailed; ms_error("Authentication requested during CardDAV request sending, and username/password weren't provided"); linphone_carddav_sync_done(query->context, FALSE, "Authentication requested during CardDAV request sending, and username/password weren't provided"); } @@ -331,18 +356,33 @@ static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { uri = belle_generic_uri_parse(query->url); if (!uri) { + LinphoneCardDavContext *cdc = query->context; + if (cdc && cdc->sync_done_cb) { + cdc->sync_done_cb(cdc, FALSE, "Could not send request, URL is invalid"); + } belle_sip_error("Could not send request, URL %s is invalid", query->url); - query->status = LinphoneCardDavQueryStatusFailed; return; } - req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), belle_sip_header_create("Depth", query->depth), NULL); + if (query->depth) { + req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), belle_sip_header_create("Depth", query->depth), NULL); + } else if (query->ifmatch) { + req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), belle_sip_header_create("If-Match", query->ifmatch), NULL); + } else { + if (strcmp(query->method, "PUT")) { + req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), belle_sip_header_create("If-None-Match", "*"), NULL); + } else { + req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), NULL); + } + } if (!req) { + LinphoneCardDavContext *cdc = query->context; + if (cdc && cdc->sync_done_cb) { + cdc->sync_done_cb(cdc, FALSE, "Could not create belle_http_request_t"); + } belle_sip_object_unref(uri); belle_sip_error("Could not create belle_http_request_t"); - query->status = LinphoneCardDavQueryStatusFailed; return; } - query->status = LinphoneCardDavQueryStatusPending; bh = belle_sip_memory_body_handler_new_copy_from_buffer(query->body, strlen(query->body), NULL, NULL); belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(bh)); @@ -354,12 +394,106 @@ static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { belle_http_provider_send_request(query->context->lc->http_provider, req, l); } +static LinphoneCardDavQuery* linphone_carddav_create_put_query(LinphoneCardDavContext *cdc, LinphoneVCard *lvc) { + LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); + query->context = cdc; + query->depth = NULL; + query->ifmatch = linphone_vcard_get_etag(lvc); + query->body = linphone_vcard_as_vcard4_string(lvc); + query->method = "PUT"; + query->url = linphone_vcard_get_url(lvc); + query->type = LinphoneCardDavQueryTypePut; + return query; +} + +static char* generate_url_from_server_address_and_uid(const char *server_url) { + if (server_url) { + char uuid[32]; + if (sal_generate_uuid(uuid, sizeof(uuid)) == 0) { + char url[300]; + snprintf(url, sizeof(url), "%s/linphone-%s.vcf", server_url, uuid); + ms_debug("Generated url is %s", url); + return ms_strdup(url); + } + } + return NULL; +} + void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { - //TODO + LinphoneVCard *lvc = linphone_friend_get_vcard(lf); + if (lvc && linphone_vcard_get_uid(lvc)) { + LinphoneCardDavQuery *query = NULL; + + if (!linphone_vcard_get_url(lvc)) { + char *url = generate_url_from_server_address_and_uid(cdc->server_url); + linphone_vcard_set_url(lvc, url); + ms_free(url); + } + + query = linphone_carddav_create_put_query(cdc, lvc); + query->user_data = linphone_friend_ref(lf); + linphone_carddav_send_query(query); + } else { + const char *msg = NULL; + if (!lvc) { + msg = "LinphoneVCard is NULL"; + } else if (!linphone_vcard_get_url(lvc)) { + msg = "LinphoneVCard doesn't have an UID"; + } + + if (msg) { + ms_error("%s", msg); + } + + if (cdc && cdc->sync_done_cb) { + cdc->sync_done_cb(cdc, FALSE, msg); + } + } +} + +static LinphoneCardDavQuery* linphone_carddav_create_delete_query(LinphoneCardDavContext *cdc, LinphoneVCard *lvc) { + LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); + query->context = cdc; + query->depth = NULL; + query->ifmatch = linphone_vcard_get_etag(lvc); + query->body = linphone_vcard_as_vcard4_string(lvc); + query->method = "DELETE"; + query->url = linphone_vcard_get_url(lvc); + query->type = LinphoneCardDavQueryTypeDelete; + return query; } void linphone_carddav_delete_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { - //TODO + LinphoneVCard *lvc = linphone_friend_get_vcard(lf); + if (lvc && linphone_vcard_get_uid(lvc) && linphone_vcard_get_etag(lvc)) { + LinphoneCardDavQuery *query = NULL; + + if (!linphone_vcard_get_url(lvc)) { + char *url = generate_url_from_server_address_and_uid(cdc->server_url); + linphone_vcard_set_url(lvc, url); + ms_free(url); + } + + query = linphone_carddav_create_delete_query(cdc, lvc); + linphone_carddav_send_query(query); + } else { + const char *msg = NULL; + if (!lvc) { + msg = "LinphoneVCard is NULL"; + } else if (!linphone_vcard_get_uid(lvc)) { + msg = "LinphoneVCard doesn't have an UID"; + } else if (!linphone_vcard_get_etag(lvc)) { + msg = "LinphoneVCard doesn't have an eTag"; + } + + if (msg) { + ms_error("%s", msg); + } + + if (cdc && cdc->sync_done_cb) { + cdc->sync_done_cb(cdc, FALSE, msg); + } + } } void linphone_carddav_set_synchronization_done_callback(LinphoneCardDavContext *cdc, LinphoneCardDavSynchronizationDoneCb cb) { @@ -382,11 +516,11 @@ static LinphoneCardDavQuery* linphone_carddav_create_propfind_query(LinphoneCard LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); query->context = cdc; query->depth = "0"; + query->ifmatch = NULL; query->body = ""; query->method = "PROPFIND"; query->url = cdc->server_url; query->type = LinphoneCardDavQueryTypePropfind; - query->status = LinphoneCardDavQueryStatusIdle; return query; } @@ -399,11 +533,11 @@ static LinphoneCardDavQuery* linphone_carddav_create_addressbook_query(LinphoneC LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); query->context = cdc; query->depth = "1"; + query->ifmatch = NULL; query->body = ""; query->method = "REPORT"; query->url = cdc->server_url; query->type = LinphoneCardDavQueryTypeAddressbookQuery; - query->status = LinphoneCardDavQueryStatusIdle; return query; } @@ -414,22 +548,22 @@ void linphone_carddav_fetch_vcards(LinphoneCardDavContext *cdc) { static LinphoneCardDavQuery* linphone_carddav_create_addressbook_multiget_query(LinphoneCardDavContext *cdc, MSList *vcards) { LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); - char body[(ms_list_size(vcards)+1)*100]; + char body[(ms_list_size(vcards)+1)*300]; MSList *iterator = vcards; query->context = cdc; query->depth = "1"; + query->ifmatch = NULL; query->method = "REPORT"; query->url = cdc->server_url; query->type = LinphoneCardDavQueryTypeAddressbookMultiget; - query->status = LinphoneCardDavQueryStatusIdle; sprintf(body, "%s", ""); while (iterator) { LinphoneCardDavResponse *response = (LinphoneCardDavResponse *)iterator->data; if (response) { - char temp_body[100]; - sprintf(temp_body, "%s", response->url); + char temp_body[300]; + snprintf(temp_body, sizeof(temp_body), "%s", response->url); sprintf(body, "%s%s", body, temp_body); iterator = ms_list_next(iterator); } diff --git a/coreapi/carddav.h b/coreapi/carddav.h index 1a8a22b26..dac895066 100644 --- a/coreapi/carddav.h +++ b/coreapi/carddav.h @@ -23,22 +23,22 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef __cplusplus extern "C" { #endif + +/** + * @addtogroup carddav_vcard + * @{ + */ typedef struct _LinphoneCardDavContext LinphoneCardDavContext; typedef enum _LinphoneCardDavQueryType { LinphoneCardDavQueryTypePropfind, LinphoneCardDavQueryTypeAddressbookQuery, - LinphoneCardDavQueryTypeAddressbookMultiget + LinphoneCardDavQueryTypeAddressbookMultiget, + LinphoneCardDavQueryTypePut, + LinphoneCardDavQueryTypeDelete } LinphoneCardDavQueryType; -typedef enum _LinphoneCardDavQueryStatus { - LinphoneCardDavQueryStatusIdle, - LinphoneCardDavQueryStatusPending, - LinphoneCardDavQueryStatusOk, - LinphoneCardDavQueryStatusFailed -} LinphoneCardDavQueryStatus; - typedef struct _LinphoneCardDavQuery LinphoneCardDavQuery; typedef struct _LinphoneCardDavResponse LinphoneCardDavResponse; @@ -157,6 +157,10 @@ void linphone_carddav_fetch_vcards(LinphoneCardDavContext *cdc); */ void linphone_carddav_pull_vcards(LinphoneCardDavContext *cdc, MSList *vcards_to_pull); +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/coreapi/private.h b/coreapi/private.h index afeb75781..03ae84a36 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1244,8 +1244,9 @@ struct _LinphoneCardDavQuery { const char *method; const char *body; const char *depth; + const char *ifmatch; + void *user_data; LinphoneCardDavQueryType type; - LinphoneCardDavQueryStatus status; }; struct _LinphoneCardDavResponse { diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index c8d94c5b2..c9b9153bf 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "vcard.h" #include "belcard/belcard.hpp" #include "belcard/belcard_parser.hpp" +#include "sal/sal.h" struct _LinphoneVCard { shared_ptr belCard; @@ -27,20 +28,24 @@ struct _LinphoneVCard { const char *url; }; -extern "C" LinphoneVCard* linphone_vcard_new(void) { +#ifdef __cplusplus +extern "C" { +#endif + +LinphoneVCard* linphone_vcard_new(void) { LinphoneVCard* vCard = (LinphoneVCard*) ms_new0(LinphoneVCard, 1); vCard->belCard = belcard::BelCardGeneric::create(); return vCard; } -extern "C" void linphone_vcard_free(LinphoneVCard *vCard) { +void linphone_vcard_free(LinphoneVCard *vCard) { if (!vCard) return; vCard->belCard.reset(); ms_free(vCard); } -extern "C" MSList* linphone_vcard_list_from_vcard4_file(const char *filename) { +MSList* linphone_vcard_list_from_vcard4_file(const char *filename) { MSList *result = NULL; if (filename && ortp_file_exist(filename) == 0) { belcard::BelCardParser parser = belcard::BelCardParser::getInstance(); @@ -57,7 +62,7 @@ extern "C" MSList* linphone_vcard_list_from_vcard4_file(const char *filename) { return result; } -extern "C" MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer) { +MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer) { MSList *result = NULL; if (buffer) { belcard::BelCardParser parser = belcard::BelCardParser::getInstance(); @@ -74,7 +79,7 @@ extern "C" MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer) { return result; } -extern "C" LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer) { +LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer) { LinphoneVCard *vCard = NULL; if (buffer) { belcard::BelCardParser parser = belcard::BelCardParser::getInstance(); @@ -89,13 +94,13 @@ extern "C" LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buff return vCard; } -extern "C" const char * linphone_vcard_as_vcard4_string(LinphoneVCard *vCard) { +const char * linphone_vcard_as_vcard4_string(LinphoneVCard *vCard) { if (!vCard) return NULL; return vCard->belCard->toFoldedString().c_str(); } -extern "C" void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name) { +void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name) { if (!vCard || !name) return; shared_ptr fn = belcard::BelCardGeneric::create(); @@ -103,14 +108,14 @@ extern "C" void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *n vCard->belCard->setFullName(fn); } -extern "C" const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard) { +const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard) { if (!vCard) return NULL; const char *result = vCard->belCard->getFullName() ? vCard->belCard->getFullName()->getValue().c_str() : NULL; return result; } -extern "C" void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char *sip_address) { +void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char *sip_address) { if (!vCard || !sip_address) return; shared_ptr impp = belcard::BelCardGeneric::create(); @@ -118,7 +123,7 @@ extern "C" void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char vCard->belCard->addImpp(impp); } -extern "C" void linphone_vcard_remove_sip_address(LinphoneVCard *vCard, const char *sip_address) { +void linphone_vcard_remove_sip_address(LinphoneVCard *vCard, const char *sip_address) { if (!vCard) return; for (auto it = vCard->belCard->getImpp().begin(); it != vCard->belCard->getImpp().end(); ++it) { @@ -130,7 +135,7 @@ extern "C" void linphone_vcard_remove_sip_address(LinphoneVCard *vCard, const ch } } -extern "C" void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const char *sip_address) { +void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const char *sip_address) { if (!vCard || !sip_address) return; if (vCard->belCard->getImpp().size() > 0) { @@ -143,7 +148,7 @@ extern "C" void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const } } -extern "C" MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) { +MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) { MSList *result = NULL; if (!vCard) return NULL; @@ -156,27 +161,56 @@ extern "C" MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) return result; } -extern "C" const char* linphone_vcard_get_uid(const LinphoneVCard *vCard) { +bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard) { + char uuid[64]; + + if (vCard) { + if (linphone_vcard_get_uid(vCard)) { + return FALSE; + } + if (sal_generate_uuid(uuid, sizeof(uuid)) == 0) { + char vcard_uuid[sizeof(uuid)+4]; + snprintf(vcard_uuid, sizeof(vcard_uuid), "urn:%s", uuid); + linphone_vcard_set_uid(vCard, ms_strdup(vcard_uuid)); + return TRUE; + } + } + return FALSE; +} + +void linphone_vcard_set_uid(LinphoneVCard *vCard, const char *uid) { + if (!vCard || !uid) return; + + shared_ptr uniqueId = belcard::BelCardGeneric::create(); + uniqueId->setValue(uid); + vCard->belCard->setUniqueId(uniqueId); +} + +const char* linphone_vcard_get_uid(const LinphoneVCard *vCard) { if (vCard && vCard->belCard->getUniqueId()) { return vCard->belCard->getUniqueId()->getValue().c_str(); } return NULL; } -extern "C" void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag) { +void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag) { vCard->etag = ms_strdup(etag); } -extern "C" const char* linphone_vcard_get_etag(const LinphoneVCard *vCard) { +const char* linphone_vcard_get_etag(const LinphoneVCard *vCard) { if (!vCard) return NULL; return vCard->etag; } -extern "C" void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url) { +void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url) { vCard->url = ms_strdup(url); } -extern "C" const char* linphone_vcard_get_url(const LinphoneVCard *vCard) { +const char* linphone_vcard_get_url(const LinphoneVCard *vCard) { if (!vCard) return NULL; return vCard->url; -} \ No newline at end of file +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/coreapi/vcard.h b/coreapi/vcard.h index c8eeec45d..f9a0782d3 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -32,7 +32,7 @@ extern "C" #endif /** - * @addtogroup buddy_list + * @addtogroup carddav_vcard * @{ */ @@ -119,12 +119,54 @@ LINPHONE_PUBLIC void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, */ LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard); +/** + * Generates a random unique id for the vCard. + * If is required to be able to synchronize the vCard with a CardDAV server + * @param[in] vCard the LinphoneVCard + * @return TRUE if operation is successful, otherwise FALSE (for example if it already has an unique ID) + */ +LINPHONE_PUBLIC bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard); + +/** + * Sets the unique ID of the vCard + * @param[in] vCard the LinphoneVCard + * @param[in] uid the unique id + */ +void linphone_vcard_set_uid(LinphoneVCard *vCard, const char *uid); + +/** + * Gets the UID of the vCard + * @param[in] vCard the LinphoneVCard + * @return the UID of the vCard, otherwise NULL + */ const char* linphone_vcard_get_uid(const LinphoneVCard *vCard); +/** + * Sets the eTAG of the vCard + * @param[in] vCard the LinphoneVCard + * @param[in] etag the eTAG + */ void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag); + +/** + * Gets the eTag of the vCard + * @param[in] vCard the LinphoneVCard + * @return the eTag of the vCard in the CardDAV server, otherwise NULL + */ const char* linphone_vcard_get_etag(const LinphoneVCard *vCard); +/** + * Sets the URL of the vCard + * @param[in] vCard the LinphoneVCard + * @param[in] url the URL + */ void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url); + +/** + * Gets the URL of the vCard + * @param[in] vCard the LinphoneVCard + * @return the URL of the vCard in the CardDAV server, otherwise NULL + */ const char* linphone_vcard_get_url(const LinphoneVCard *vCard); /** diff --git a/coreapi/vcard_stubs.c b/coreapi/vcard_stubs.c index 148858e09..4309e7b7b 100644 --- a/coreapi/vcard_stubs.c +++ b/coreapi/vcard_stubs.c @@ -71,6 +71,14 @@ MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) { return NULL; } +bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard) { + return FALSE; +} + +void linphone_vcard_set_uid(LinphoneVCard *vCard, const char *uid) { + +} + const char* linphone_vcard_get_uid(const LinphoneVCard *vCard) { return NULL; } diff --git a/include/sal/sal.h b/include/sal/sal.h index d8106f6b7..c1ed0dc21 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -618,6 +618,7 @@ void sal_verify_server_certificates(Sal *ctx, bool_t verify); void sal_verify_server_cn(Sal *ctx, bool_t verify); void sal_set_uuid(Sal*ctx, const char *uuid); int sal_create_uuid(Sal*ctx, char *uuid, size_t len); +int sal_generate_uuid(char *uuid, size_t len); LINPHONE_PUBLIC void sal_enable_test_features(Sal*ctx, bool_t enabled); void sal_use_no_initial_route(Sal *ctx, bool_t enabled); diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index c146ac7f7..774aec654 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -200,7 +200,6 @@ typedef struct _LinphoneCardDAVStats { static void carddav_sync_done(LinphoneCardDavContext *c, bool_t success, const char *message) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_TRUE(success); - linphone_carddav_destroy(c); stats->sync_done_count++; } @@ -250,6 +249,7 @@ static void carddav_sync(void) { BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); ms_free(stats); + linphone_carddav_destroy(c); linphone_core_manager_destroy(manager); } @@ -288,6 +288,7 @@ static void carddav_sync_2(void) { ms_free(stats); unlink(friends_db); ms_free(friends_db); + linphone_carddav_destroy(c); linphone_core_manager_destroy(manager); } @@ -325,6 +326,40 @@ static void carddav_sync_3(void) { ms_free(stats); unlink(friends_db); ms_free(friends_db); + linphone_carddav_destroy(c); + linphone_core_manager_destroy(manager); +} + +static void carddav_sync_4(void) { + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); + LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Margaux Clerc\r\nIMPP;TYPE=work:sip:margaux@sip.linphone.org\r\nEND:VCARD\r\n"); + LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); + + BC_ASSERT_PTR_NOT_NULL_FATAL(c); + BC_ASSERT_PTR_NOT_NULL(c->server_url); + BC_ASSERT_PTR_NOT_NULL(c->username); + BC_ASSERT_PTR_NOT_NULL(c->ha1); + + linphone_carddav_set_user_data(c, stats); + linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); + + BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); + BC_ASSERT_TRUE(linphone_vcard_generate_unique_id(lvc)); + BC_ASSERT_PTR_NOT_NULL(linphone_vcard_get_uid(lvc)); + + linphone_carddav_put_vcard(c, lf); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + + linphone_carddav_delete_vcard(c, lf); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 2, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i"); + + linphone_friend_unref(lf); + ms_free(stats); + linphone_carddav_destroy(c); linphone_core_manager_destroy(manager); } @@ -346,6 +381,7 @@ test_t vcard_tests[] = { { "CardDAV synchronization", carddav_sync }, { "CardDAV synchronization 2", carddav_sync_2 }, { "CardDAV synchronization 3", carddav_sync_3 }, + { "CardDAV synchronization 4", carddav_sync_4 }, #else { "Dummy test", dummy_test } #endif From 3bc3b24e103e87b367e6210b24f314d2675790b6 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 8 Jan 2016 17:45:50 +0100 Subject: [PATCH 053/121] Set vCard URL and eTag when new one downloaded --- coreapi/carddav.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index f9ea99f73..559977f04 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -90,8 +90,20 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * LinphoneCardDavResponse *vCard = (LinphoneCardDavResponse *)vCards->data; if (vCard) { LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer(vCard->vcard); - LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); - MSList *local_friend = ms_list_find_custom(localFriends, (int (*)(const void*, const void*))find_matching_friend, lf); + LinphoneFriend *lf = NULL; + MSList *local_friend = NULL; + + if (lvc) { + // Compute downloaded vCards' URL and save it (+ eTag) + char *vCard_name = strrchr(vCard->url, '/'); + char full_url[300]; + snprintf(full_url, sizeof(full_url), "%s%s", cdc->server_url, vCard_name); + linphone_vcard_set_url(lvc, full_url); + linphone_vcard_set_etag(lvc, vCard->etag); + } + lf = linphone_friend_new_from_vcard(lvc); + local_friend = ms_list_find_custom(localFriends, (int (*)(const void*, const void*))find_matching_friend, lf); + if (local_friend) { LinphoneFriend *lf2 = (LinphoneFriend *)local_friend->data; if (cdc->contact_updated_cb) { From 13928df051fa5af7aa8c932966c5efbae286b654 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 8 Jan 2016 18:05:00 +0100 Subject: [PATCH 054/121] Do not set a body for the DELETE CardDAV method --- coreapi/carddav.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 559977f04..f24a3463f 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -396,8 +396,10 @@ static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { return; } - bh = belle_sip_memory_body_handler_new_copy_from_buffer(query->body, strlen(query->body), NULL, NULL); - belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(bh)); + if (query->body) { + bh = belle_sip_memory_body_handler_new_copy_from_buffer(query->body, strlen(query->body), NULL, NULL); + belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), bh ? BELLE_SIP_BODY_HANDLER(bh) : NULL); + } cbs.process_response = process_response_from_carddav_request; cbs.process_io_error = process_io_error_from_carddav_request; @@ -468,7 +470,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_delete_query(LinphoneCardDa query->context = cdc; query->depth = NULL; query->ifmatch = linphone_vcard_get_etag(lvc); - query->body = linphone_vcard_as_vcard4_string(lvc); + query->body = NULL; query->method = "DELETE"; query->url = linphone_vcard_get_url(lvc); query->type = LinphoneCardDavQueryTypeDelete; From 7afa6b6f59687dcedb15828c4b49f3c88a6d13b3 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 11 Jan 2016 11:08:26 +0100 Subject: [PATCH 055/121] Added test for vcard update + added code to download complete vcard if put doesn't return an eTag --- coreapi/carddav.c | 30 +++++++++++++++++++++++------- coreapi/friend.c | 9 ++++++++- tester/vcard_tester.c | 13 +++++++++++++ 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index f24a3463f..4f4c904de 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -302,16 +302,32 @@ static void process_response_from_carddav_request(void *data, const belle_http_r { belle_sip_header_t *header = belle_sip_message_get_header((belle_sip_message_t *)event->response, "ETag"); LinphoneFriend *lf = (LinphoneFriend *)query->user_data; - if (lf) { - LinphoneVCard *lvc = linphone_friend_get_vcard(lf); - if (header && lvc && !linphone_vcard_get_etag(lvc)) { + LinphoneVCard *lvc = linphone_friend_get_vcard(lf); + if (lf && lvc) { + if (header) { const char *etag = belle_sip_header_get_unparsed_value(header); - ms_debug("eTag for newly created vCard is: %s", etag); + if (!linphone_vcard_get_etag(lvc)) { + ms_debug("eTag for newly created vCard is: %s", etag); + } else { + ms_debug("eTag for updated vCard is: %s", etag); + } linphone_vcard_set_etag(lvc, etag); + + linphone_carddav_sync_done(query->context, TRUE, ""); + linphone_friend_unref(lf); + } else { + // For some reason, server didn't return the eTag of the updated/created vCard + // We need to do a GET on the vCard to get the correct one + MSList *vcard = NULL; + LinphoneCardDavResponse *response = (LinphoneCardDavResponse *)ms_new0(LinphoneCardDavResponse, 1); + response->url = linphone_vcard_get_url(lvc); + response->context = query->context; + vcard = ms_list_append(vcard, response); + linphone_carddav_pull_vcards(query->context, vcard); + ms_list_free(vcard); } - linphone_carddav_sync_done(query->context, TRUE, ""); - linphone_friend_unref(lf); - } else { + } + else { linphone_carddav_sync_done(query->context, FALSE, "No LinphoneFriend found in user_date field of query"); } } diff --git a/coreapi/friend.c b/coreapi/friend.c index 99d652cb9..4bb0e7448 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -777,10 +777,17 @@ void linphone_friend_destroy(LinphoneFriend *lf) { } LinphoneVCard* linphone_friend_get_vcard(LinphoneFriend *fr) { - return fr->vcard; + if (fr) { + return fr->vcard; + } + return NULL; } void linphone_friend_set_vcard(LinphoneFriend *fr, LinphoneVCard *vcard) { + if (!fr) { + return; + } + if (fr->vcard) { linphone_vcard_free(fr->vcard); } diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 774aec654..1cda3a1f7 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -206,6 +206,7 @@ static void carddav_sync_done(LinphoneCardDavContext *c, bool_t success, const c static void carddav_new_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_PTR_NOT_NULL_FATAL(lf); + linphone_core_add_friend(c->lc, lf); linphone_friend_unref(lf); stats->new_contact_count++; } @@ -230,6 +231,8 @@ static void carddav_sync(void) { LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + const MSList *friends = NULL; + LinphoneFriend *lf = NULL; BC_ASSERT_PTR_NOT_NULL_FATAL(c); BC_ASSERT_PTR_NOT_NULL(c->server_url); @@ -248,6 +251,16 @@ static void carddav_sync(void) { wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + friends = linphone_core_get_friend_list(manager->lc); + BC_ASSERT_PTR_NOT_NULL_FATAL(friends); + lf = (LinphoneFriend *)friends->data; + linphone_carddav_put_vcard(c, lf); + + wait_for_until(manager->lc, NULL, &stats->updated_contact_count, 1, 2000); + BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i"); + ms_free(stats); linphone_carddav_destroy(c); linphone_core_manager_destroy(manager); From 379ac0e21ec6ab4255733b59c7712b3745775b4b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 11 Jan 2016 11:46:02 +0100 Subject: [PATCH 056/121] Fixed a leak of LinphoneAddress and replaced some linphone_address_destroy by linphone_address_unref --- coreapi/carddav.c | 21 ++++++++++----------- coreapi/friend.c | 13 +++++++------ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 4f4c904de..e871b51bc 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -391,17 +391,8 @@ static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { belle_sip_error("Could not send request, URL %s is invalid", query->url); return; } - if (query->depth) { - req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), belle_sip_header_create("Depth", query->depth), NULL); - } else if (query->ifmatch) { - req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), belle_sip_header_create("If-Match", query->ifmatch), NULL); - } else { - if (strcmp(query->method, "PUT")) { - req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), belle_sip_header_create("If-None-Match", "*"), NULL); - } else { - req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), NULL); - } - } + req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), NULL); + if (!req) { LinphoneCardDavContext *cdc = query->context; if (cdc && cdc->sync_done_cb) { @@ -412,6 +403,14 @@ static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { return; } + if (query->depth) { + belle_sip_message_add_header((belle_sip_message_t *)req, belle_sip_header_create("Depth", query->depth)); + } else if (query->ifmatch) { + belle_sip_message_add_header((belle_sip_message_t *)req, belle_sip_header_create("If-Match", query->ifmatch)); + } else if (strcmp(query->method, "PUT")) { + belle_sip_message_add_header((belle_sip_message_t *)req, belle_sip_header_create("If-None-Match", "*")); + } + if (query->body) { bh = belle_sip_memory_body_handler_new_copy_from_buffer(query->body, strlen(query->body), NULL, NULL); belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), bh ? BELLE_SIP_BODY_HANDLER(bh) : NULL); diff --git a/coreapi/friend.c b/coreapi/friend.c index 4bb0e7448..773b9e78e 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -143,7 +143,7 @@ LinphoneFriend *linphone_friend_new_with_address(const char *addr){ } fr=linphone_friend_new(); linphone_friend_set_address(fr,linphone_address); - linphone_address_destroy(linphone_address); + linphone_address_unref(linphone_address); return fr; } @@ -180,7 +180,7 @@ void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char linphone_address_set_display_name(id,NULL); linphone_address_set_username(id,uri); *result=linphone_address_as_string(id); - linphone_address_destroy(id); + linphone_address_unref(id); } } if (*result){ @@ -191,7 +191,7 @@ void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char } }else { *result=linphone_address_as_string(fr); - linphone_address_destroy(fr); + linphone_address_unref(fr); } } @@ -200,7 +200,7 @@ int linphone_friend_set_address(LinphoneFriend *lf, const LinphoneAddress *addr) LinphoneVCard *vcard = NULL; linphone_address_clean(fr); - if (lf->uri != NULL) linphone_address_destroy(lf->uri); + if (lf->uri != NULL) linphone_address_unref(lf->uri); lf->uri = fr; vcard = linphone_friend_get_vcard(lf); @@ -318,7 +318,7 @@ static void _linphone_friend_release_ops(LinphoneFriend *lf){ static void _linphone_friend_destroy(LinphoneFriend *lf){ _linphone_friend_release_ops(lf); if (lf->presence != NULL) linphone_presence_model_unref(lf->presence); - if (lf->uri!=NULL) linphone_address_destroy(lf->uri); + if (lf->uri!=NULL) linphone_address_unref(lf->uri); if (lf->info!=NULL) buddy_info_free(lf->info); if (lf->vcard != NULL) linphone_vcard_free(lf->vcard); } @@ -857,7 +857,7 @@ LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard) { linphone_address = linphone_address_new(sipAddress); if (linphone_address) { linphone_friend_set_address(fr, linphone_address); - linphone_address_destroy(linphone_address); + linphone_address_unref(linphone_address); } } linphone_friend_set_name(fr, name); @@ -1032,6 +1032,7 @@ static int create_friend(void *data, int argc, char **argv, char **colName) { LinphoneAddress *addr = linphone_address_new(argv[1]); lf = linphone_friend_new(); linphone_friend_set_address(lf, addr); + linphone_address_unref(addr); } linphone_friend_set_inc_subscribe_policy(lf, atoi(argv[2])); linphone_friend_send_subscribe(lf, atoi(argv[3])); From cd6409da3f67c06f590436577d6fbe942bdb2d4e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 11 Jan 2016 12:10:11 +0100 Subject: [PATCH 057/121] Fix last found by liblinphone_tester in carddav part --- coreapi/carddav.c | 23 ++++++++++++++++++----- coreapi/private.h | 1 + tester/vcard_tester.c | 6 +++--- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index e871b51bc..e55646b19 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -281,6 +281,19 @@ end: return result; } +static void linphone_carddav_query_free(LinphoneCardDavQuery *query) { + if (!query) { + return; + } + + if (query->http_request_listener) { + belle_sip_object_unref(query->http_request_listener); + query->http_request_listener = NULL; + } + + ms_free(query); +} + static void process_response_from_carddav_request(void *data, const belle_http_response_event_t *event) { LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data; @@ -347,13 +360,13 @@ static void process_response_from_carddav_request(void *data, const belle_http_r } else { linphone_carddav_sync_done(query->context, FALSE, "No response found"); } - ms_free(query); + linphone_carddav_query_free(query); } static void process_io_error_from_carddav_request(void *data, const belle_sip_io_error_event_t *event) { LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data; ms_error("I/O error during CardDAV request sending"); - ms_free(query); + linphone_carddav_query_free(query); linphone_carddav_sync_done(query->context, FALSE, "I/O error during CardDAV request sending"); } @@ -371,13 +384,13 @@ static void process_auth_requested_from_carddav_request(void *data, belle_sip_au } } else { ms_error("Authentication requested during CardDAV request sending, and username/password weren't provided"); + linphone_carddav_query_free(query); linphone_carddav_sync_done(query->context, FALSE, "Authentication requested during CardDAV request sending, and username/password weren't provided"); } } static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { belle_http_request_listener_callbacks_t cbs = { 0 }; - belle_http_request_listener_t *l = NULL; belle_generic_uri_t *uri = NULL; belle_http_request_t *req = NULL; belle_sip_memory_body_handler_t *bh = NULL; @@ -419,8 +432,8 @@ static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { cbs.process_response = process_response_from_carddav_request; cbs.process_io_error = process_io_error_from_carddav_request; cbs.process_auth_requested = process_auth_requested_from_carddav_request; - l = belle_http_request_listener_create_from_callbacks(&cbs, query); - belle_http_provider_send_request(query->context->lc->http_provider, req, l); + query->http_request_listener = belle_http_request_listener_create_from_callbacks(&cbs, query); + belle_http_provider_send_request(query->context->lc->http_provider, req, query->http_request_listener); } static LinphoneCardDavQuery* linphone_carddav_create_put_query(LinphoneCardDavContext *cdc, LinphoneVCard *lvc) { diff --git a/coreapi/private.h b/coreapi/private.h index 03ae84a36..67eefa2d6 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1245,6 +1245,7 @@ struct _LinphoneCardDavQuery { const char *body; const char *depth; const char *ifmatch; + belle_http_request_listener_t *http_request_listener; void *user_data; LinphoneCardDavQueryType type; }; diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 1cda3a1f7..339bf33a7 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -91,7 +91,7 @@ static void friends_if_no_db_set(void) { friends = linphone_core_get_friend_list(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); - linphone_address_destroy(addr); + linphone_address_unref(addr); linphone_core_manager_destroy(manager); } @@ -117,7 +117,7 @@ static void friends_migration(void) { end: unlink(friends_db); ms_free(friends_db); - linphone_address_destroy(addr); + linphone_address_unref(addr); friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); linphone_core_manager_destroy(manager); } @@ -184,7 +184,7 @@ static void friends_sqlite_storage(void) { end: unlink(friends_db); ms_free(friends_db); - linphone_address_destroy(addr); + linphone_address_unref(addr); friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); linphone_core_manager_destroy(manager); } From 90ddebf9dbf7ac0a9e37cc9114eeef35ccbf6653 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 11 Jan 2016 16:11:55 +0100 Subject: [PATCH 058/121] Fixed warning when importing vcard with name but no sip uri --- coreapi/friend.c | 9 ++++++--- coreapi/friendlist.c | 2 +- tester/vcard_tester.c | 16 +++++++++------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index 773b9e78e..586077be3 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -229,11 +229,12 @@ int linphone_friend_set_name(LinphoneFriend *lf, const char *name){ } } - if (!fr) { + if (!fr && !vcard) { ms_warning("linphone_friend_set_address() must be called before linphone_friend_set_name() to be able to set display name."); return -1; + } else if (fr) { + linphone_address_set_display_name(fr, name); } - linphone_address_set_display_name(fr, name); return 0; } @@ -860,7 +861,9 @@ LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard) { linphone_address_unref(linphone_address); } } - linphone_friend_set_name(fr, name); + if (name) { + linphone_friend_set_name(fr, name); + } return fr; } diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index ca1bb1308..6d54f5d2e 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -313,7 +313,6 @@ LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *lis ms_warning("Friend %s already in list [%s], ignored.", tmp ? tmp : "unknown", list->display_name); if (tmp) ms_free(tmp); } else { - lf->in_list = TRUE; return linphone_friend_list_import_friend(list, lf); } return LinphoneFriendListOK; @@ -322,6 +321,7 @@ LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *lis LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf) { if ((lf->lc != NULL) || (lf->uri == NULL)) return LinphoneFriendListInvalidFriend; list->friends = ms_list_append(list->friends, linphone_friend_ref(lf)); + lf->in_list = TRUE; return LinphoneFriendListOK; } diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 339bf33a7..5584dc0f9 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -252,14 +252,16 @@ static void carddav_sync(void) { BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); friends = linphone_core_get_friend_list(manager->lc); - BC_ASSERT_PTR_NOT_NULL_FATAL(friends); - lf = (LinphoneFriend *)friends->data; - linphone_carddav_put_vcard(c, lf); + BC_ASSERT_PTR_NOT_NULL(friends); + if (friends) { + lf = (LinphoneFriend *)friends->data; + linphone_carddav_put_vcard(c, lf); - wait_for_until(manager->lc, NULL, &stats->updated_contact_count, 1, 2000); - BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i"); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); - BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->updated_contact_count, 1, 2000); + BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i"); + } ms_free(stats); linphone_carddav_destroy(c); From 855f9a9b39963bd293629a4d64be6b11f6518ad2 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 11 Jan 2016 16:48:26 +0100 Subject: [PATCH 059/121] Fixed typo when asking server for vCard version 4 (was working with sabre/dav v3.0.5 but I guess it was a bug and it seems it was fixed in v3.0.6) --- coreapi/carddav.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index e55646b19..e46401646 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -600,7 +600,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_addressbook_multiget_query( query->url = cdc->server_url; query->type = LinphoneCardDavQueryTypeAddressbookMultiget; - sprintf(body, "%s", ""); + sprintf(body, "%s", ""); while (iterator) { LinphoneCardDavResponse *response = (LinphoneCardDavResponse *)iterator->data; if (response) { From add00537ef8de55791db0627efe1d7eea40113fc Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 12 Jan 2016 10:10:03 +0100 Subject: [PATCH 060/121] Test add/remove friends from core in tester + fix test with new CardDAV server --- coreapi/carddav.c | 1 + tester/vcard_tester.c | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index e46401646..c7a911c80 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -100,6 +100,7 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * snprintf(full_url, sizeof(full_url), "%s%s", cdc->server_url, vCard_name); linphone_vcard_set_url(lvc, full_url); linphone_vcard_set_etag(lvc, vCard->etag); + ms_debug("Downloaded vCard etag/url are %s and %s", vCard->etag, full_url); } lf = linphone_friend_new_from_vcard(lvc); local_friend = ms_list_find_custom(localFriends, (int (*)(const void*, const void*))find_matching_friend, lf); diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 5584dc0f9..48e6abc21 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -214,16 +214,19 @@ static void carddav_new_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { static void carddav_removed_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_PTR_NOT_NULL_FATAL(lf); + linphone_core_remove_friend(c->lc, lf); linphone_friend_unref(lf); stats->removed_contact_count++; } -static void carddav_updated_contact(LinphoneCardDavContext *c, LinphoneFriend *lf1, LinphoneFriend *lf2) { +static void carddav_updated_contact(LinphoneCardDavContext *c, LinphoneFriend *new_lf, LinphoneFriend *old_lf) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); - BC_ASSERT_PTR_NOT_NULL_FATAL(lf1); - BC_ASSERT_PTR_NOT_NULL_FATAL(lf2); - linphone_friend_unref(lf1); - linphone_friend_unref(lf2); + BC_ASSERT_PTR_NOT_NULL_FATAL(new_lf); + BC_ASSERT_PTR_NOT_NULL_FATAL(old_lf); + linphone_core_remove_friend(c->lc, old_lf); + linphone_core_add_friend(c->lc, new_lf); + linphone_friend_unref(new_lf); + linphone_friend_unref(old_lf); stats->updated_contact_count++; } @@ -311,7 +314,7 @@ static void carddav_sync_3(void) { LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); - LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nUID:79100a4d-2806-482f-bf27-0e09dc47149b\r\nFN:Sylvain Berfini\r\nIMPP;TYPE=work:sip:sylvain@sip.linphone.org\r\nEND:VCARD\r\n"); + LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nFN:Sylvain Berfini\r\nIMPP;TYPE=work:sip:sylvain@sip.linphone.org\r\nEND:VCARD\r\n"); LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); From 3ae31c37ae0edcd34c140abed87feb4f958acc86 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 12 Jan 2016 16:48:51 +0100 Subject: [PATCH 061/121] Added vcard.h include to fix compilation broken by conference.cc --- coreapi/private.h | 1 + 1 file changed, 1 insertion(+) diff --git a/coreapi/private.h b/coreapi/private.h index 698b4518a..d0c00596b 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -35,6 +35,7 @@ #include "sipsetup.h" #include "quality_reporting.h" #include "ringtoneplayer.h" +#include "vcard.h" #include #include From 1d262248587f003b4615f6b1f14b6d8ee8d332b2 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 13 Jan 2016 17:05:49 +0100 Subject: [PATCH 062/121] Started CardDAV integration into liblinphone friends API --- coreapi/Makefile.am | 6 +- coreapi/account_creator.h | 3 +- coreapi/carddav.c | 75 +++++++++----------- coreapi/carddav.h | 8 ++- coreapi/conference.h | 3 +- coreapi/friend.c | 20 +++++- coreapi/friendlist.c | 141 ++++++++++++++++++++++++++++++++++++-- coreapi/friendlist.h | 110 +++++++++++++++++++++++++++++ coreapi/linphonecore.c | 82 +--------------------- coreapi/linphonecore.h | 63 +---------------- coreapi/private.h | 39 +++++------ coreapi/vcard.cc | 34 ++++++++- coreapi/vcard.h | 39 +++++++---- coreapi/vcard_stubs.c | 8 +++ tester/Makefile.am | 3 +- tester/rcfiles/carddav_rc | 11 --- tester/vcard_tester.c | 135 +++++++++++++++++++++++------------- 17 files changed, 486 insertions(+), 294 deletions(-) delete mode 100644 tester/rcfiles/carddav_rc diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 0dc338351..01582a10d 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -43,6 +43,7 @@ linphone_include_HEADERS=\ sipsetup.h \ xml2lpc.h \ xmlrpc.h \ + vcard.h \ carddav.h lib_LTLIBRARIES=liblinphone.la @@ -120,10 +121,10 @@ liblinphone_la_SOURCES+=linphone_tunnel_stubs.c linphone_tunnel.h endif if BUILD_VCARD -liblinphone_la_SOURCES+=vcard.cc vcard.h +liblinphone_la_SOURCES+=vcard.cc liblinphone_la_CXXFLAGS=-std=c++11 else -liblinphone_la_SOURCES+=vcard_stubs.c vcard.h +liblinphone_la_SOURCES+=vcard_stubs.c endif liblinphone_la_LDFLAGS= -version-info $(LIBLINPHONE_SO_VERSION) -no-undefined @@ -157,6 +158,7 @@ liblinphone_la_LIBADD= \ AM_CPPFLAGS=\ + -DIN_LINPHONE \ -I$(top_srcdir) -I$(top_srcdir)/include -I$(builddir) \ $(ORTP_CFLAGS) \ $(MEDIASTREAMER_CFLAGS) \ diff --git a/coreapi/account_creator.h b/coreapi/account_creator.h index 41730dcfa..94c16670a 100644 --- a/coreapi/account_creator.h +++ b/coreapi/account_creator.h @@ -20,13 +20,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef LINPHONE_ACCOUNT_CREATOR_H_ #define LINPHONE_ACCOUNT_CREATOR_H_ +#include "linphonecore.h" #ifdef __cplusplus extern "C" { #endif -#include "linphonecore.h" - /** * @addtogroup misc * @{ diff --git a/coreapi/carddav.c b/coreapi/carddav.c index c7a911c80..449561e14 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -20,29 +20,28 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphonecore.h" #include "private.h" -LinphoneCardDavContext* linphone_core_create_carddav_context(LinphoneCore *lc) { +LinphoneCardDavContext* linphone_carddav_context_new(LinphoneFriendList *lfl) { LinphoneCardDavContext *carddav_context = NULL; - if (!lc) { + if (!lfl || !lfl->uri) { return NULL; } #ifdef VCARD_ENABLED carddav_context = (LinphoneCardDavContext *)ms_new0(LinphoneCardDavContext, 1); - carddav_context->lc = lc; - carddav_context->server_url = linphone_core_get_carddav_server_url(lc); - carddav_context->ctag = linphone_core_get_carddav_last_ctag(lc); - carddav_context->username = linphone_core_get_carddav_username(lc); - carddav_context->password = linphone_core_get_carddav_password(lc); - carddav_context->ha1 = linphone_core_get_carddav_ha1(lc); + carddav_context->friend_list = linphone_friend_list_ref(lfl); #else ms_error("vCard isn't available (maybe it wasn't compiled), can't do CardDAV sync"); #endif return carddav_context; } -void linphone_carddav_destroy(LinphoneCardDavContext *cdc) { +void linphone_carddav_context_destroy(LinphoneCardDavContext *cdc) { if (cdc) { + if (cdc->friend_list) { + linphone_friend_list_unref(cdc->friend_list); + cdc->friend_list = NULL; + } ms_free(cdc); } } @@ -62,7 +61,7 @@ void linphone_carddav_synchronize(LinphoneCardDavContext *cdc) { static void linphone_carddav_sync_done(LinphoneCardDavContext *cdc, bool_t success, const char *msg) { if (success) { ms_debug("CardDAV sync successful, saving new cTag: %i", cdc->ctag); - linphone_core_set_carddav_current_ctag(cdc->lc, cdc->ctag); + linphone_friend_list_update_revision(cdc->friend_list, cdc->ctag); } else { ms_error("CardDAV sync failure: %s", msg); } @@ -75,8 +74,12 @@ static void linphone_carddav_sync_done(LinphoneCardDavContext *cdc, bool_t succe static int find_matching_friend(LinphoneFriend *lf1, LinphoneFriend *lf2) { LinphoneVCard *lvc1 = linphone_friend_get_vcard(lf1); LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf2); - const char *uid1 = linphone_vcard_get_uid(lvc1); - const char *uid2 = linphone_vcard_get_uid(lvc2); + const char *uid1 = NULL, *uid2 = NULL; + if (!lvc1 || !lvc2) { + return 1; + } + uid1 = linphone_vcard_get_uid(lvc1); + uid2 = linphone_vcard_get_uid(lvc2); if (!uid1 || !uid2) { return 1; } @@ -85,7 +88,7 @@ static int find_matching_friend(LinphoneFriend *lf1, LinphoneFriend *lf2) { static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList *vCards) { if (vCards != NULL && ms_list_size(vCards) > 0) { - MSList *localFriends = linphone_core_fetch_friends_from_db(cdc->lc); + MSList *friends = cdc->friend_list->friends; while (vCards) { LinphoneCardDavResponse *vCard = (LinphoneCardDavResponse *)vCards->data; if (vCard) { @@ -97,13 +100,13 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * // Compute downloaded vCards' URL and save it (+ eTag) char *vCard_name = strrchr(vCard->url, '/'); char full_url[300]; - snprintf(full_url, sizeof(full_url), "%s%s", cdc->server_url, vCard_name); + snprintf(full_url, sizeof(full_url), "%s%s", cdc->friend_list->uri, vCard_name); linphone_vcard_set_url(lvc, full_url); linphone_vcard_set_etag(lvc, vCard->etag); ms_debug("Downloaded vCard etag/url are %s and %s", vCard->etag, full_url); } lf = linphone_friend_new_from_vcard(lvc); - local_friend = ms_list_find_custom(localFriends, (int (*)(const void*, const void*))find_matching_friend, lf); + local_friend = ms_list_find_custom(friends, (int (*)(const void*, const void*))find_matching_friend, lf); if (local_friend) { LinphoneFriend *lf2 = (LinphoneFriend *)local_friend->data; @@ -121,7 +124,6 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * } vCards = ms_list_next(vCards); } - localFriends = ms_list_free_with_data(localFriends, (void (*)(void *))linphone_friend_unref); } ms_list_free(vCards); linphone_carddav_sync_done(cdc, TRUE, ""); @@ -169,8 +171,12 @@ end: static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend *lf) { LinphoneVCard *lvc1 = linphone_vcard_new_from_vcard4_buffer(response->vcard); LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf); - const char *uid1 = linphone_vcard_get_uid(lvc1); - const char *uid2 = linphone_vcard_get_uid(lvc2); + const char *uid1 = NULL, *uid2 = NULL; + if (!lvc1 || !lvc2) { + return 1; + } + uid1 = linphone_vcard_get_uid(lvc1); + uid2 = linphone_vcard_get_uid(lvc2); linphone_vcard_free(lvc1); if (!uid1 || !uid2) { return 1; @@ -180,8 +186,7 @@ static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList *vCards) { if (vCards != NULL && ms_list_size(vCards) > 0) { - MSList *localFriends = linphone_core_fetch_friends_from_db(cdc->lc); - MSList *friends = localFriends; + MSList *friends = cdc->friend_list->friends; while (friends) { LinphoneFriend *lf = (LinphoneFriend *)friends->data; if (lf) { @@ -208,7 +213,6 @@ static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList } friends = ms_list_next(friends); } - localFriends = ms_list_free_with_data(localFriends, (void (*)(void *))linphone_friend_unref); linphone_carddav_pull_vcards(cdc, vCards); } ms_list_free(vCards); @@ -372,22 +376,7 @@ static void process_io_error_from_carddav_request(void *data, const belle_sip_io } static void process_auth_requested_from_carddav_request(void *data, belle_sip_auth_event_t *event) { - LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data; - LinphoneCardDavContext *context = query->context; - - if (context->username && (context->password || context->ha1)) { - belle_sip_auth_event_set_username(event, context->username); - if (context->password) { - belle_sip_auth_event_set_passwd(event, context->password); - } - if (context->ha1) { - belle_sip_auth_event_set_ha1(event, context->ha1); - } - } else { - ms_error("Authentication requested during CardDAV request sending, and username/password weren't provided"); - linphone_carddav_query_free(query); - linphone_carddav_sync_done(query->context, FALSE, "Authentication requested during CardDAV request sending, and username/password weren't provided"); - } + //TODO //FIXME: find a way around this } static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { @@ -434,7 +423,7 @@ static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { cbs.process_io_error = process_io_error_from_carddav_request; cbs.process_auth_requested = process_auth_requested_from_carddav_request; query->http_request_listener = belle_http_request_listener_create_from_callbacks(&cbs, query); - belle_http_provider_send_request(query->context->lc->http_provider, req, query->http_request_listener); + belle_http_provider_send_request(query->context->friend_list->lc->http_provider, req, query->http_request_listener); } static LinphoneCardDavQuery* linphone_carddav_create_put_query(LinphoneCardDavContext *cdc, LinphoneVCard *lvc) { @@ -468,7 +457,7 @@ void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) LinphoneCardDavQuery *query = NULL; if (!linphone_vcard_get_url(lvc)) { - char *url = generate_url_from_server_address_and_uid(cdc->server_url); + char *url = generate_url_from_server_address_and_uid(cdc->friend_list->uri); linphone_vcard_set_url(lvc, url); ms_free(url); } @@ -512,7 +501,7 @@ void linphone_carddav_delete_vcard(LinphoneCardDavContext *cdc, LinphoneFriend * LinphoneCardDavQuery *query = NULL; if (!linphone_vcard_get_url(lvc)) { - char *url = generate_url_from_server_address_and_uid(cdc->server_url); + char *url = generate_url_from_server_address_and_uid(cdc->friend_list->uri); linphone_vcard_set_url(lvc, url); ms_free(url); } @@ -562,7 +551,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_propfind_query(LinphoneCard query->ifmatch = NULL; query->body = ""; query->method = "PROPFIND"; - query->url = cdc->server_url; + query->url = cdc->friend_list->uri; query->type = LinphoneCardDavQueryTypePropfind; return query; } @@ -579,7 +568,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_addressbook_query(LinphoneC query->ifmatch = NULL; query->body = ""; query->method = "REPORT"; - query->url = cdc->server_url; + query->url = cdc->friend_list->uri; query->type = LinphoneCardDavQueryTypeAddressbookQuery; return query; } @@ -598,7 +587,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_addressbook_multiget_query( query->depth = "1"; query->ifmatch = NULL; query->method = "REPORT"; - query->url = cdc->server_url; + query->url = cdc->friend_list->uri; query->type = LinphoneCardDavQueryTypeAddressbookMultiget; sprintf(body, "%s", ""); diff --git a/coreapi/carddav.h b/coreapi/carddav.h index dac895066..8ef3d70dd 100644 --- a/coreapi/carddav.h +++ b/coreapi/carddav.h @@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef LINPHONE_CARDDAV_H #define LINPHONE_CARDDAV_H +#include "linphonecore.h" + #ifdef __cplusplus extern "C" { #endif @@ -65,16 +67,16 @@ typedef void (*LinphoneCardDavSynchronizationDoneCb)(LinphoneCardDavContext *cdc /** * Creates a CardDAV context for all related operations - * @param lc LinphoneCore object + * @param lfl LinphoneFriendList object * @return LinphoneCardDavContext object if vCard support is enabled and server URL is available, NULL otherwise */ -LINPHONE_PUBLIC LinphoneCardDavContext* linphone_core_create_carddav_context(LinphoneCore *lc); +LINPHONE_PUBLIC LinphoneCardDavContext* linphone_carddav_context_new(LinphoneFriendList *lfl); /** * Deletes a LinphoneCardDavContext object * @param cdc LinphoneCardDavContext object */ -LINPHONE_PUBLIC void linphone_carddav_destroy(LinphoneCardDavContext *cdc); +LINPHONE_PUBLIC void linphone_carddav_context_destroy(LinphoneCardDavContext *cdc); /** * Sets a user pointer to the LinphoneCardDAVContext object diff --git a/coreapi/conference.h b/coreapi/conference.h index 6192850a3..5c4b4b403 100644 --- a/coreapi/conference.h +++ b/coreapi/conference.h @@ -26,11 +26,12 @@ #ifndef CONFERENCE_H #define CONFERENCE_H +#include "linphonecore.h" + #ifdef __cplusplus extern "C" { #endif -#include "linphonecore.h" //typedef struct _LinphoneConference LinphoneConference; diff --git a/coreapi/friend.c b/coreapi/friend.c index 586077be3..bacab20f0 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -155,8 +155,8 @@ void* linphone_friend_get_user_data(const LinphoneFriend *lf){ return lf->user_data; } -bool_t linphone_friend_in_list(const LinphoneFriend *lf){ - return lf->in_list; +bool_t linphone_friend_in_list(const LinphoneFriend *lf) { + return lf->friend_list != NULL; } void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char **result){ @@ -529,13 +529,27 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc) { } void linphone_friend_edit(LinphoneFriend *fr) { + if (fr && fr->vcard) { + linphone_vcard_compute_md5_hash(fr->vcard); + } } void linphone_friend_done(LinphoneFriend *fr) { + const char *previous_md5 = NULL; + ms_return_if_fail(fr); - if (!fr->lc || !fr->in_list) return; + if (!fr->lc || !fr->friend_list) return; linphone_friend_apply(fr, fr->lc); linphone_friend_save(fr, fr->lc); + + if (fr && fr->vcard) { + previous_md5 = linphone_vcard_get_md5_hash(fr->vcard); + linphone_vcard_compute_md5_hash(fr->vcard); + if (previous_md5 && strcmp(previous_md5, linphone_vcard_get_md5_hash(fr->vcard)) != 0) { + ms_debug("vCard's md5 has changed, mark friend as dirty"); + fr->friend_list->dirty_friends_to_update = ms_list_append(fr->friend_list->dirty_friends_to_update, fr); + } + } } LinphoneFriend * linphone_core_create_friend(LinphoneCore *lc) { diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index c8a602146..e78eb9a91 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -22,6 +22,55 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriendListCbs); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneFriendListCbs, belle_sip_object_t, + NULL, // destroy + NULL, // clone + NULL, // Marshall + FALSE +); + +static LinphoneFriendListCbs * linphone_friend_list_cbs_new(void) { + return belle_sip_object_new(LinphoneFriendListCbs); +} + +LinphoneFriendListCbs * linphone_friend_list_get_callbacks(const LinphoneFriendList *list) { + return list->cbs; +} + +LinphoneFriendListCbs * linphone_friend_list_cbs_ref(LinphoneFriendListCbs *cbs) { + belle_sip_object_ref(cbs); + return cbs; +} + +void linphone_friend_list_cbs_unref(LinphoneFriendListCbs *cbs) { + belle_sip_object_unref(cbs); +} + +void *linphone_friend_list_cbs_get_user_data(const LinphoneFriendListCbs *cbs) { + return cbs->user_data; +} + +void linphone_friend_list_cbs_set_user_data(LinphoneFriendListCbs *cbs, void *ud) { + cbs->user_data = ud; +} + +LinphoneFriendListContactCreatedCb linphone_friend_list_cbs_get_contact_created(const LinphoneFriendListCbs *cbs) { + return cbs->contact_created_cb; +} + +void linphone_friend_list_cbs_set_contact_created(LinphoneFriendListCbs *cbs, LinphoneFriendListContactCreatedCb cb) { + cbs->contact_created_cb = cb; +} + +LinphoneFriendListContactDeletedCb linphone_friend_list_cbs_get_contact_deleted(const LinphoneFriendListCbs *cbs) { + return cbs->contact_deleted_cb; +} + +void linphone_friend_list_cbs_set_contact_deleted(LinphoneFriendListCbs *cbs, LinphoneFriendListContactDeletedCb cb) { + cbs->contact_deleted_cb = cb; +} static char * create_resource_list_xml(const LinphoneFriendList *list) { char *xml_content = NULL; @@ -219,6 +268,7 @@ static bool_t linphone_friend_list_has_subscribe_inactive(const LinphoneFriendLi static LinphoneFriendList * linphone_friend_list_new(void) { LinphoneFriendList *list = belle_sip_object_new(LinphoneFriendList); + list->cbs = linphone_friend_list_cbs_new(); belle_sip_object_ref(list); return list; } @@ -228,7 +278,10 @@ static void linphone_friend_list_destroy(LinphoneFriendList *list) { if (list->rls_uri != NULL) ms_free(list->rls_uri); if (list->content_digest != NULL) ms_free(list->content_digest); if (list->event != NULL) linphone_event_unref(list->event); + if (list->uri != NULL) ms_free(list->uri); + if (list->cbs) linphone_friend_list_cbs_unref(list->cbs); list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))linphone_friend_unref); + list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))_linphone_friend_release); } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriendList); @@ -259,7 +312,12 @@ void _linphone_friend_list_release(LinphoneFriendList *list){ linphone_event_unref(list->event); list->event = NULL; } + if (list->cbs) { + linphone_friend_list_cbs_unref(list->cbs); + list->cbs = NULL; + } list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release); + list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))_linphone_friend_release); belle_sip_object_unref(list); } @@ -304,10 +362,10 @@ void linphone_friend_list_set_rls_uri(LinphoneFriendList *list, const char *rls_ } LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf) { - if (lf->uri == NULL || lf->in_list) { + if (lf->uri == NULL || lf->friend_list) { if (!lf->uri) ms_error("linphone_friend_list_add_friend(): invalid friend, no sip uri"); - if (lf->in_list) + if (lf->friend_list) ms_error("linphone_friend_list_add_friend(): invalid friend, already in list"); return LinphoneFriendListInvalidFriend; } @@ -326,24 +384,81 @@ LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *lis LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf) { if ((lf->lc != NULL) || (lf->uri == NULL)) return LinphoneFriendListInvalidFriend; list->friends = ms_list_append(list->friends, linphone_friend_ref(lf)); - lf->in_list = TRUE; + list->dirty_friends_to_update = ms_list_append(list->dirty_friends_to_update, linphone_friend_ref(lf)); + lf->friend_list = list; return LinphoneFriendListOK; } +static void carddav_done(LinphoneCardDavContext *cdc, bool_t success, const char *msg) { + linphone_carddav_context_destroy(cdc); +} + LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *lf) { MSList *elem = ms_list_find(list->friends, lf); + LinphoneCardDavContext *cdc = linphone_carddav_context_new(list); if (elem == NULL) return LinphoneFriendListNonExistentFriend; #ifdef FRIENDS_SQL_STORAGE_ENABLED linphone_core_remove_friend_from_db(lf->lc, lf); #endif + if (cdc) { + cdc->sync_done_cb = carddav_done; + linphone_carddav_delete_vcard(cdc, lf); + } - lf->in_list = FALSE; + lf->friend_list = NULL; linphone_friend_unref(lf); list->friends = ms_list_remove_link(list->friends, elem); return LinphoneFriendListOK; } +void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list) { + LinphoneCardDavContext *cdc = linphone_carddav_context_new(list); + MSList *dirty_friends = list->dirty_friends_to_update; + + if (cdc) { + cdc->sync_done_cb = carddav_done; + while (dirty_friends) { + LinphoneFriend *lf = (LinphoneFriend *)dirty_friends->data; + if (lf) { + linphone_carddav_put_vcard(cdc, lf); + } + dirty_friends = ms_list_next(dirty_friends); + } + } + list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref); +} + +static void carddav_created(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { + if (cdc && cdc->friend_list->cbs->contact_created_cb) { + LinphoneFriendList *lfl = cdc->friend_list; + lfl->friends = ms_list_append(lfl->friends, linphone_friend_ref(lf)); + cdc->friend_list->cbs->contact_created_cb(lfl, linphone_friend_ref(lf)); + } + linphone_friend_unref(lf); +} + +static void carddav_removed(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { + if (cdc && cdc->friend_list->cbs->contact_deleted_cb) { + LinphoneFriendList *lfl = cdc->friend_list; + MSList *elem = ms_list_find(lfl->friends, lf); + lfl->friends = ms_list_remove_link(lfl->friends, elem); + cdc->friend_list->cbs->contact_deleted_cb(lfl, linphone_friend_ref(lf)); + } + linphone_friend_unref(lf); +} + +void linphone_friend_list_synchronize_friends_from_server(LinphoneFriendList *list) { + LinphoneCardDavContext *cdc = linphone_carddav_context_new(list); + + if (cdc) { + cdc->contact_created_cb = carddav_created; + cdc->contact_removed_cb = carddav_removed; + cdc->sync_done_cb = carddav_done; + linphone_carddav_synchronize(cdc); + } +} + LinphoneFriend * linphone_friend_list_find_friend_by_address(const LinphoneFriendList *list, const LinphoneAddress *address) { LinphoneFriend *lf = NULL; const MSList *elem; @@ -487,3 +602,21 @@ void linphone_friend_list_notify_presence_received(LinphoneFriendList *list, Lin linphone_content_unref(first_part); } } + +const char * linphone_friend_list_get_uri(const LinphoneFriendList *list) { + return list->uri; +} + +void linphone_friend_list_set_uri(LinphoneFriendList *list, const char *uri) { + if (list->uri != NULL) { + ms_free(list->uri); + list->uri = NULL; + } + if (uri != NULL) { + list->uri = ms_strdup(uri); + } +} + +void linphone_friend_list_update_revision(LinphoneFriendList *list, int rev) { + list->revision = rev; +} \ No newline at end of file diff --git a/coreapi/friendlist.h b/coreapi/friendlist.h index e69cae707..9efe9824b 100644 --- a/coreapi/friendlist.h +++ b/coreapi/friendlist.h @@ -174,6 +174,116 @@ LINPHONE_PUBLIC void linphone_friend_list_update_subscriptions(LinphoneFriendLis **/ LINPHONE_PUBLIC void linphone_friend_list_notify_presence(LinphoneFriendList *list, LinphonePresenceModel *presence); +/** + * Get the URI associated with the friend list. + * @param[in] list LinphoneFriendList object. + * @return The URI associated with the friend list. +**/ +LINPHONE_PUBLIC const char * linphone_friend_list_get_uri(const LinphoneFriendList *list); + +/** + * Set the URI associated with the friend list. + * @param[in] list LinphoneFriendList object. + * @param[in] rls_uri The URI to associate with the friend list. +**/ +LINPHONE_PUBLIC void linphone_friend_list_set_uri(LinphoneFriendList *list, const char *uri); + +/** + * Sets the revision from the last synchronization. + * @param[in] list LinphoneFriendList object. + * @param[in] rev The revision + */ +void linphone_friend_list_update_revision(LinphoneFriendList *list, int rev); + +/** + * An object to handle the callbacks for LinphoneFriend synchronization. +**/ +typedef struct _LinphoneFriendListCbs LinphoneFriendListCbs; + +/** + * Callback used to notify a new contact has been created on the CardDAV server and downloaded locally +**/ +typedef void (*LinphoneFriendListContactCreatedCb)(LinphoneFriendList *list, LinphoneFriend *lf); + +/** + * Callback used to notify a contact has been deleted on the CardDAV server +**/ +typedef void (*LinphoneFriendListContactDeletedCb)(LinphoneFriendList *list, LinphoneFriend *lf); + +/** + * Get the LinphoneFriendListCbs object associated with a LinphoneFriendList. + * @param[in] request LinphoneXmlRpcRequest object + * @return The LinphoneFriendListCbs object associated with the LinphoneFriendList. +**/ +LINPHONE_PUBLIC LinphoneFriendListCbs * linphone_friend_list_get_callbacks(const LinphoneFriendList *list); + +/** + * Acquire a reference to a LinphoneFriendListCbs object. + * @param[in] cbs LinphoneFriendListCbs object. + * @return The same LinphoneFriendListCbs object. +**/ +LINPHONE_PUBLIC LinphoneFriendListCbs * linphone_friend_list_cbs_ref(LinphoneFriendListCbs *cbs); + +/** + * Release a reference to a LinphoneFriendListCbs object. + * @param[in] cbs LinphoneFriendListCbs object. +**/ +LINPHONE_PUBLIC void linphone_friend_list_cbs_unref(LinphoneFriendListCbs *cbs); + +/** + * Retrieve the user pointer associated with a LinphoneFriendListCbs object. + * @param[in] cbs LinphoneFriendListCbs object. + * @return The user pointer associated with the LinphoneFriendListCbs object. +**/ +LINPHONE_PUBLIC void *linphone_friend_list_cbs_get_user_data(const LinphoneFriendListCbs *cbs); + +/** + * Assign a user pointer to a LinphoneFriendListCbs object. + * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] ud The user pointer to associate with the LinphoneFriendListCbs object. +**/ +LINPHONE_PUBLIC void linphone_friend_list_cbs_set_user_data(LinphoneFriendListCbs *cbs, void *ud); + +/** + * Get the contact created callback. + * @param[in] cbs LinphoneFriendListCbs object. + * @return The current contact created callback. +**/ +LINPHONE_PUBLIC LinphoneFriendListContactCreatedCb linphone_friend_list_cbs_get_contact_created(const LinphoneFriendListCbs *cbs); + +/** + * Set the contact created callback. + * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] cb The contact created to be used. +**/ +LINPHONE_PUBLIC void linphone_friend_list_cbs_set_contact_created(LinphoneFriendListCbs *cbs, LinphoneFriendListContactCreatedCb cb); + +/** + * Get the contact deleted callback. + * @param[in] cbs LinphoneFriendListCbs object. + * @return The current contact deleted callback. +**/ +LINPHONE_PUBLIC LinphoneFriendListContactDeletedCb linphone_friend_list_cbs_get_contact_deleted(const LinphoneFriendListCbs *cbs); + +/** + * Set the contact deleted callback. + * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] cb The contact deleted to be used. +**/ +LINPHONE_PUBLIC void linphone_friend_list_cbs_set_contact_deleted(LinphoneFriendListCbs *cbs, LinphoneFriendListContactDeletedCb cb); + +/** + * + * @param[in] list LinphoneFriendList object. + */ +LINPHONE_PUBLIC void linphone_friend_list_synchronize_friends_from_server(LinphoneFriendList *list); + +/** + * + * @param[in] list LinphoneFriendList object. + */ +void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list); + /** * @} */ diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 0c89d5aa5..bba34d427 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2736,6 +2736,9 @@ void linphone_core_iterate(LinphoneCore *lc){ if (lp_config_needs_commit(lc->config)) { lp_config_sync(lc->config); } + if (lc->friendlist->dirty_friends_to_update) { + linphone_friend_list_update_dirty_friends(lc->friendlist); + } } if (liblinphone_serialize_logs == TRUE) { @@ -7431,85 +7434,6 @@ const char *linphone_stream_type_to_string(const LinphoneStreamType type) { return "INVALID"; } -/***************************************************************************** - * CardDAV interface * - ****************************************************************************/ - -void linphone_core_set_carddav_server_url(LinphoneCore *lc, const char *carddav_server_url) { - if (lc && carddav_server_url) { - LpConfig *lpc = linphone_core_get_config(lc); - lp_config_set_string(lpc, "carddav", "server_url", carddav_server_url); - } -} - -const char *linphone_core_get_carddav_server_url(LinphoneCore *lc) { - if (lc) { - LpConfig *lpc = linphone_core_get_config(lc); - return lp_config_get_string(lpc, "carddav", "server_url", NULL); - } - return NULL; -} - -void linphone_core_set_carddav_username(LinphoneCore *lc, const char *username) { - if (lc && username) { - LpConfig *lpc = linphone_core_get_config(lc); - lp_config_set_string(lpc, "carddav", "username", username); - } -} - -const char *linphone_core_get_carddav_username(LinphoneCore *lc) { - if (lc) { - LpConfig *lpc = linphone_core_get_config(lc); - return lp_config_get_string(lpc, "carddav", "username", NULL); - } - return NULL; -} - -void linphone_core_set_carddav_password(LinphoneCore *lc, const char *password) { - if (lc && password) { - LpConfig *lpc = linphone_core_get_config(lc); - lp_config_set_string(lpc, "carddav", "password", password); - } -} - -const char *linphone_core_get_carddav_password(LinphoneCore *lc) { - if (lc) { - LpConfig *lpc = linphone_core_get_config(lc); - return lp_config_get_string(lpc, "carddav", "password", NULL); - } - return NULL; -} - -void linphone_core_set_carddav_ha1(LinphoneCore *lc, const char *ha1) { - if (lc && ha1) { - LpConfig *lpc = linphone_core_get_config(lc); - lp_config_set_string(lpc, "carddav", "ha1", ha1); - } -} - -const char *linphone_core_get_carddav_ha1(LinphoneCore *lc) { - if (lc) { - LpConfig *lpc = linphone_core_get_config(lc); - return lp_config_get_string(lpc, "carddav", "ha1", NULL); - } - return NULL; -} - -void linphone_core_set_carddav_current_ctag(LinphoneCore *lc, int ctag) { - if (lc) { - LpConfig *lpc = linphone_core_get_config(lc); - lp_config_set_int(lpc, "carddav", "ctag", ctag); - } -} - -int linphone_core_get_carddav_last_ctag(LinphoneCore *lc) { - if (lc) { - LpConfig *lpc = linphone_core_get_config(lc); - return lp_config_get_int(lpc, "carddav", "ctag", 0); - } - return 0; -} - LinphoneRingtonePlayer *linphone_core_get_ringtoneplayer(LinphoneCore *lc) { return lc->ringtoneplayer; } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 1369365ac..c728a521a 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -417,7 +417,6 @@ LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy); #include "event.h" #include "linphonefriend.h" #include "xmlrpc.h" -#include "carddav.h" #else #include "linphone/buffer.h" #include "linphone/call_log.h" @@ -426,7 +425,6 @@ LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy); #include "linphone/event.h" #include "linphone/linphonefriend.h" #include "linphone/xmlrpc.h" -#include "linphone/carddav.h" #endif LINPHONE_PUBLIC LinphoneAddress * linphone_address_new(const char *addr); @@ -1211,9 +1209,11 @@ LINPHONE_PUBLIC LinphoneAuthInfo * linphone_auth_info_new_from_config_file(LpCon #ifdef IN_LINPHONE #include "account_creator.h" #include "friendlist.h" +#include "carddav.h" #else #include "linphone/account_creator.h" #include "linphone/friendlist.h" +#include "linphone/carddav.h" #endif @@ -4360,65 +4360,6 @@ LINPHONE_PUBLIC LinphoneTransportType linphone_transport_parse(const char* trans */ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *lc); -/***************************************************************************** - * CardDAV interface * - ****************************************************************************/ - -/** - * Sets the CardDAV server URL - * @param lc LinphoneCore object - * @param carddav_server_url the URL to the CardDAV server - */ -LINPHONE_PUBLIC void linphone_core_set_carddav_server_url(LinphoneCore *lc, const char *carddav_server_url); - -/** - * Gets the CardDAV server URL if set - * @param lc LinphoneCore object - * @return the URL to the CardDAV server if set, otherwise NULL - */ -LINPHONE_PUBLIC const char *linphone_core_get_carddav_server_url(LinphoneCore *lc); -/** - * Sets the CardDAV server username - * @param lc LinphoneCore object - * @param username the username for the CardDAV server - */ -LINPHONE_PUBLIC void linphone_core_set_carddav_username(LinphoneCore *lc, const char *username); - -/** - * Gets the CardDAV server username - * @param lc LinphoneCore object - * @return the username for the CardDAV server if set, otherwise NULL - */ -LINPHONE_PUBLIC const char *linphone_core_get_carddav_username(LinphoneCore *lc); - -/** - * Sets the CardDAV server password - * @param lc LinphoneCore object - * @param password the password for the CardDAV server - */ -LINPHONE_PUBLIC void linphone_core_set_carddav_password(LinphoneCore *lc, const char *password); - -/** - * Gets the CardDAV server password - * @param lc LinphoneCore object - * @return the password for the CardDAV server if set, otherwise NULL - */ -LINPHONE_PUBLIC const char *linphone_core_get_carddav_password(LinphoneCore *lc); - -/** - * Sets the CardDAV server hashed password - * @param lc LinphoneCore object - * @param ha1 the hashed password for the CardDAV server - */ -LINPHONE_PUBLIC void linphone_core_set_carddav_ha1(LinphoneCore *lc, const char *ha1); - -/** - * Gets the CardDAV server hashed password - * @param lc LinphoneCore object - * @return the hashed password for the CardDAV server if set, otherwise NULL - */ -LINPHONE_PUBLIC const char *linphone_core_get_carddav_ha1(LinphoneCore *lc); - typedef struct _LinphoneRingtonePlayer LinphoneRingtonePlayer; LINPHONE_PUBLIC LinphoneRingtonePlayer *linphone_core_get_ringtoneplayer(LinphoneCore *lc); diff --git a/coreapi/private.h b/coreapi/private.h index d0c00596b..e778bc8f9 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -675,7 +675,6 @@ struct _LinphoneFriend{ struct _LinphoneCore *lc; BuddyInfo *info; char *refkey; - bool_t in_list; bool_t subscribe; bool_t subscribe_active; bool_t inc_subscribe_pending; @@ -684,10 +683,19 @@ struct _LinphoneFriend{ bool_t presence_received; LinphoneVCard *vcard; unsigned int storage_id; + LinphoneFriendList *friend_list; }; BELLE_SIP_DECLARE_VPTR(LinphoneFriend); +struct _LinphoneFriendListCbs { + belle_sip_object_t base; + void *user_data; + LinphoneFriendListContactCreatedCb contact_created_cb; + LinphoneFriendListContactDeletedCb contact_deleted_cb; +}; + +BELLE_SIP_DECLARE_VPTR(LinphoneFriendListCbs); struct _LinphoneFriendList { belle_sip_object_t base; @@ -699,11 +707,17 @@ struct _LinphoneFriendList { MSList *friends; unsigned char *content_digest; int expected_notification_version; + unsigned int storage_id; + char *uri; + MSList *dirty_friends_to_update; + int revision; + LinphoneFriendListCbs *cbs; }; BELLE_SIP_DECLARE_VPTR(LinphoneFriendList); + typedef struct sip_config { char *contact; @@ -1227,12 +1241,8 @@ BELLE_SIP_DECLARE_VPTR(LinphoneAccountCreator); ****************************************************************************/ struct _LinphoneCardDavContext { - LinphoneCore *lc; + LinphoneFriendList *friend_list; int ctag; - const char *server_url; - const char *username; - const char *password; - const char *ha1; void *user_data; LinphoneCardDavContactCreatedCb contact_created_cb; LinphoneCardDavContactUpdatedCb contact_updated_cb; @@ -1259,20 +1269,6 @@ struct _LinphoneCardDavResponse { const char *vcard; }; -/** - * Sets the CardDAV server current cTag - * @param lc LinphoneCore object - * @param ctag the current cTag for the CardDAV server - */ -void linphone_core_set_carddav_current_ctag(LinphoneCore *lc, int ctag); - -/** - * Gets the CardDAV server last cTag - * @param lc LinphoneCore object - * @return the last cTag for the CardDAV server if set, otherwise -1 - */ -int linphone_core_get_carddav_last_ctag(LinphoneCore *lc); - /***************************************************************************** * REMOTE PROVISIONING FUNCTIONS * ****************************************************************************/ @@ -1381,7 +1377,8 @@ BELLE_SIP_TYPE_ID(LinphoneFriendList), BELLE_SIP_TYPE_ID(LinphoneXmlRpcRequest), BELLE_SIP_TYPE_ID(LinphoneXmlRpcRequestCbs), BELLE_SIP_TYPE_ID(LinphoneXmlRpcSession), -BELLE_SIP_TYPE_ID(LinphoneTunnelConfig) +BELLE_SIP_TYPE_ID(LinphoneTunnelConfig), +BELLE_SIP_TYPE_ID(LinphoneFriendListCbs) BELLE_SIP_DECLARE_TYPES_END diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index c9b9153bf..77d136642 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -24,8 +24,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. struct _LinphoneVCard { shared_ptr belCard; - const char *etag; - const char *url; + char *etag; + char *url; + char *md5; }; #ifdef __cplusplus @@ -194,6 +195,12 @@ const char* linphone_vcard_get_uid(const LinphoneVCard *vCard) { } void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag) { + if (!vCard) { + return; + } + if (vCard->etag) { + ms_free(vCard->etag); + } vCard->etag = ms_strdup(etag); } @@ -203,6 +210,12 @@ const char* linphone_vcard_get_etag(const LinphoneVCard *vCard) { } void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url) { + if (!vCard) { + return; + } + if (vCard->url) { + ms_free(vCard->url); + } vCard->url = ms_strdup(url); } @@ -211,6 +224,23 @@ const char* linphone_vcard_get_url(const LinphoneVCard *vCard) { return vCard->url; } +void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard) { + if (!vCard) { + return; + } + if (vCard->md5) { + ms_free(vCard->md5); + } + //TODO: compute md5 hash +} + +const char *linphone_vcard_get_md5_hash(LinphoneVCard *vCard) { + if (!vCard) { + return NULL; + } + return vCard->md5; +} + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/coreapi/vcard.h b/coreapi/vcard.h index f9a0782d3..70f61b41c 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -41,83 +41,83 @@ typedef struct _LinphoneVCard LinphoneVCard; /** * Creates a LinphoneVCard object that has a pointer to an empty vCard */ -LINPHONE_PUBLIC LinphoneVCard* linphone_vcard_new(void); +LinphoneVCard* linphone_vcard_new(void); /** * Deletes a LinphoneVCard object properly * @param[in] vCard the LinphoneVCard to destroy */ -LINPHONE_PUBLIC void linphone_vcard_free(LinphoneVCard *vCard); +void linphone_vcard_free(LinphoneVCard *vCard); /** * Uses belcard to parse the content of a file and returns all the vcards it contains as LinphoneVCards, or NULL if it contains none. * @param[in] file the path to the file to parse * @return \mslist{LinphoneVCard} */ -LINPHONE_PUBLIC MSList* linphone_vcard_list_from_vcard4_file(const char *file); +MSList* linphone_vcard_list_from_vcard4_file(const char *file); /** * Uses belcard to parse the content of a buffer and returns all the vcards it contains as LinphoneVCards, or NULL if it contains none. * @param[in] buffer the buffer to parse * @return \mslist{LinphoneVCard} */ -LINPHONE_PUBLIC MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer); +MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer); /** * Uses belcard to parse the content of a buffer and returns one vCard if possible, or NULL otherwise. * @param[in] buffer the buffer to parse * @return a LinphoneVCard if one could be parsed, or NULL otherwise */ -LINPHONE_PUBLIC LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer); +LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer); /** * Returns the vCard4 representation of the LinphoneVCard. * @param[in] vCard the LinphoneVCard * @return a const char * that represents the vCard */ -LINPHONE_PUBLIC const char* linphone_vcard_as_vcard4_string(LinphoneVCard *vCard); +const char* linphone_vcard_as_vcard4_string(LinphoneVCard *vCard); /** * Sets the FN attribute of the vCard (which is mandatory). * @param[in] vCard the LinphoneVCard * @param[in] name the display name to set for the vCard */ -LINPHONE_PUBLIC void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name); +void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name); /** * Returns the FN attribute of the vCard, or NULL if it isn't set yet. * @param[in] vCard the LinphoneVCard * @return the display name of the vCard, or NULL */ -LINPHONE_PUBLIC const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard); +const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard); /** * Adds a SIP address in the vCard, using the IMPP property * @param[in] vCard the LinphoneVCard * @param[in] sip_address the SIP address to add */ -LINPHONE_PUBLIC void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char *sip_address); +void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char *sip_address); /** * Removes a SIP address in the vCard (if it exists), using the IMPP property * @param[in] vCard the LinphoneVCard * @param[in] sip_address the SIP address to remove */ -LINPHONE_PUBLIC void linphone_vcard_remove_sip_address(LinphoneVCard *vCard, const char *sip_address); +void linphone_vcard_remove_sip_address(LinphoneVCard *vCard, const char *sip_address); /** * Edits the preferred SIP address in the vCard (or the first one), using the IMPP property * @param[in] vCard the LinphoneVCard * @param[in] sip_address the new SIP address */ -LINPHONE_PUBLIC void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const char *sip_address); +void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const char *sip_address); /** * Returns the list of SIP addresses (as const char *) in the vCard (all the IMPP attributes that has an URI value starting by "sip:") or NULL * @param[in] vCard the LinphoneVCard * @return \mslist{const char *} */ -LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard); +MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard); /** * Generates a random unique id for the vCard. @@ -125,7 +125,7 @@ LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vC * @param[in] vCard the LinphoneVCard * @return TRUE if operation is successful, otherwise FALSE (for example if it already has an unique ID) */ -LINPHONE_PUBLIC bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard); +bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard); /** * Sets the unique ID of the vCard @@ -169,6 +169,19 @@ void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url); */ const char* linphone_vcard_get_url(const LinphoneVCard *vCard); +/** + * Computes the md5 hash for the vCard + * @param[in] vCard the LinphoneVCard + */ +void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard); + +/** + * Computes the md5 hash for the vCard + * @param[in] vCard the LinphoneVCard + * @return the last md5 hash computed for the vCard, or NULL if it wasn't computed yet + */ +const char *linphone_vcard_get_md5_hash(LinphoneVCard *vCard); + /** * @} */ diff --git a/coreapi/vcard_stubs.c b/coreapi/vcard_stubs.c index 4309e7b7b..4f12c0415 100644 --- a/coreapi/vcard_stubs.c +++ b/coreapi/vcard_stubs.c @@ -97,4 +97,12 @@ void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url) { const char* linphone_vcard_get_url(const LinphoneVCard *vCard) { return NULL; +} + +void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard) { + +} + +const char *linphone_vcard_get_md5_hash(LinphoneVCard *vCard) { + return NULL; } \ No newline at end of file diff --git a/tester/Makefile.am b/tester/Makefile.am index ec46807a9..d2da519a5 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -69,8 +69,7 @@ RCFILES = \ rcfiles/stun_rc\ rcfiles/upnp_rc\ rcfiles/zero_length_params_rc\ - rcfiles/friends_rc\ - rcfiles/carddav_rc + rcfiles/friends_rc IMAGE_FILES = images/nowebcamCIF.jpg diff --git a/tester/rcfiles/carddav_rc b/tester/rcfiles/carddav_rc deleted file mode 100644 index c4d35f470..000000000 --- a/tester/rcfiles/carddav_rc +++ /dev/null @@ -1,11 +0,0 @@ -[net] -mtu=1300 - -[sip] -ping_with_options=0 -sip_random_port=1 - -[carddav] -server_url=http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default -username=sylvain -ha1=4747ce2517a985f2fc20234a38f068b6 \ No newline at end of file diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 48e6abc21..e838ef035 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -206,7 +206,6 @@ static void carddav_sync_done(LinphoneCardDavContext *c, bool_t success, const c static void carddav_new_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_PTR_NOT_NULL_FATAL(lf); - linphone_core_add_friend(c->lc, lf); linphone_friend_unref(lf); stats->new_contact_count++; } @@ -214,7 +213,6 @@ static void carddav_new_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { static void carddav_removed_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_PTR_NOT_NULL_FATAL(lf); - linphone_core_remove_friend(c->lc, lf); linphone_friend_unref(lf); stats->removed_contact_count++; } @@ -223,24 +221,21 @@ static void carddav_updated_contact(LinphoneCardDavContext *c, LinphoneFriend *n LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_PTR_NOT_NULL_FATAL(new_lf); BC_ASSERT_PTR_NOT_NULL_FATAL(old_lf); - linphone_core_remove_friend(c->lc, old_lf); - linphone_core_add_friend(c->lc, new_lf); linphone_friend_unref(new_lf); linphone_friend_unref(old_lf); stats->updated_contact_count++; } static void carddav_sync(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); + LinphoneCoreManager *manager = linphone_core_manager_new2("empty_rc", FALSE); LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); - const MSList *friends = NULL; - LinphoneFriend *lf = NULL; + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneCardDavContext *c = NULL; + linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + linphone_core_set_friend_list(manager->lc, lfl); + c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); - BC_ASSERT_PTR_NOT_NULL(c->server_url); - BC_ASSERT_PTR_NOT_NULL(c->username); - BC_ASSERT_PTR_NOT_NULL(c->ha1); linphone_carddav_set_user_data(c, stats); linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); @@ -254,40 +249,30 @@ static void carddav_sync(void) { wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); - friends = linphone_core_get_friend_list(manager->lc); - BC_ASSERT_PTR_NOT_NULL(friends); - if (friends) { - lf = (LinphoneFriend *)friends->data; - linphone_carddav_put_vcard(c, lf); - - wait_for_until(manager->lc, NULL, &stats->updated_contact_count, 1, 2000); - BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i"); - wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); - BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i"); - } - ms_free(stats); - linphone_carddav_destroy(c); + linphone_friend_list_unref(lfl); + linphone_carddav_context_destroy(c); linphone_core_manager_destroy(manager); } static void carddav_sync_2(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); + LinphoneCoreManager *manager = linphone_core_manager_new2("empty_rc", FALSE); LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); LinphoneFriend *lf = linphone_friend_new_with_address("\"Sylvain\" "); char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneCardDavContext *c = NULL; + + linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + linphone_core_set_friend_list(manager->lc, lfl); + c = linphone_carddav_context_new(lfl); + BC_ASSERT_PTR_NOT_NULL_FATAL(c); unlink(friends_db); linphone_core_set_friends_database_path(manager->lc, friends_db); linphone_core_add_friend(manager->lc, lf); linphone_friend_unref(lf); - BC_ASSERT_PTR_NOT_NULL_FATAL(c); - BC_ASSERT_PTR_NOT_NULL(c->server_url); - BC_ASSERT_PTR_NOT_NULL(c->username); - BC_ASSERT_PTR_NOT_NULL(c->ha1); - linphone_carddav_set_user_data(c, stats); linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); linphone_carddav_set_new_contact_callback(c, carddav_new_contact); @@ -306,28 +291,30 @@ static void carddav_sync_2(void) { ms_free(stats); unlink(friends_db); ms_free(friends_db); - linphone_carddav_destroy(c); + linphone_friend_list_unref(lfl); + linphone_carddav_context_destroy(c); linphone_core_manager_destroy(manager); } static void carddav_sync_3(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); + LinphoneCoreManager *manager = linphone_core_manager_new2("empty_rc", FALSE); LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nFN:Sylvain Berfini\r\nIMPP;TYPE=work:sip:sylvain@sip.linphone.org\r\nEND:VCARD\r\n"); LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneCardDavContext *c = NULL; + + linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + linphone_core_set_friend_list(manager->lc, lfl); + c = linphone_carddav_context_new(lfl); + BC_ASSERT_PTR_NOT_NULL_FATAL(c); unlink(friends_db); linphone_core_set_friends_database_path(manager->lc, friends_db); linphone_core_add_friend(manager->lc, lf); linphone_friend_unref(lf); - BC_ASSERT_PTR_NOT_NULL_FATAL(c); - BC_ASSERT_PTR_NOT_NULL(c->server_url); - BC_ASSERT_PTR_NOT_NULL(c->username); - BC_ASSERT_PTR_NOT_NULL(c->ha1); - linphone_carddav_set_user_data(c, stats); linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); linphone_carddav_set_new_contact_callback(c, carddav_new_contact); @@ -344,24 +331,29 @@ static void carddav_sync_3(void) { ms_free(stats); unlink(friends_db); ms_free(friends_db); - linphone_carddav_destroy(c); + linphone_friend_list_unref(lfl); + linphone_carddav_context_destroy(c); linphone_core_manager_destroy(manager); } static void carddav_sync_4(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); + LinphoneCoreManager *manager = linphone_core_manager_new2("empty_rc", FALSE); LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Margaux Clerc\r\nIMPP;TYPE=work:sip:margaux@sip.linphone.org\r\nEND:VCARD\r\n"); LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneCardDavContext *c = NULL; + linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + linphone_core_set_friend_list(manager->lc, lfl); + c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); - BC_ASSERT_PTR_NOT_NULL(c->server_url); - BC_ASSERT_PTR_NOT_NULL(c->username); - BC_ASSERT_PTR_NOT_NULL(c->ha1); linphone_carddav_set_user_data(c, stats); linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); + linphone_carddav_set_new_contact_callback(c, carddav_new_contact); + linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact); + linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact); BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); BC_ASSERT_TRUE(linphone_vcard_generate_unique_id(lvc)); @@ -377,13 +369,61 @@ static void carddav_sync_4(void) { linphone_friend_unref(lf); ms_free(stats); - linphone_carddav_destroy(c); + linphone_friend_list_unref(lfl); + linphone_carddav_context_destroy(c); + linphone_core_manager_destroy(manager); +} + +static void carddav_contact_created(LinphoneFriendList *list, LinphoneFriend *lf) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); + stats->new_contact_count++; + linphone_friend_unref(lf); +} + +static void carddav_contact_deleted(LinphoneFriendList *list, LinphoneFriend *lf) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); + stats->removed_contact_count++; + linphone_friend_unref(lf); +} + +static void carddav_integration(void) { + LinphoneCoreManager *manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Margaux Clerc\r\nIMPP;TYPE=work:sip:margaux@sip.linphone.org\r\nEND:VCARD\r\n"); + LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); + LinphoneFriendListCbs *cbs = NULL; + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + + linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + cbs = linphone_friend_list_get_callbacks(lfl); + linphone_friend_list_cbs_set_user_data(cbs, stats); + linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); + linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); + linphone_core_set_friend_list(manager->lc, lfl); + + BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); + BC_ASSERT_TRUE(linphone_vcard_generate_unique_id(lvc)); + BC_ASSERT_PTR_NOT_NULL(linphone_vcard_get_uid(lvc)); + linphone_friend_list_add_friend(lfl, lf); + wait_for_until(manager->lc, NULL, NULL, 1, 2000); + linphone_friend_list_remove_friend(lfl, lf); + wait_for_until(manager->lc, NULL, NULL, 1, 2000); + + BC_ASSERT_EQUAL(lfl->revision, 0, int, "%i"); + + linphone_friend_list_synchronize_friends_from_server(lfl); + wait_for_until(manager->lc, NULL, &stats->new_contact_count, 1, 2000); + BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i"); + BC_ASSERT_NOT_EQUAL(lfl->revision, 0, int, "%i"); + + ms_free(stats); + linphone_friend_unref(lf); + linphone_friend_list_unref(lfl); linphone_core_manager_destroy(manager); } #else static void dummy_test(void) { - } #endif @@ -400,6 +440,7 @@ test_t vcard_tests[] = { { "CardDAV synchronization 2", carddav_sync_2 }, { "CardDAV synchronization 3", carddav_sync_3 }, { "CardDAV synchronization 4", carddav_sync_4 }, + { "CardDAV integration", carddav_integration }, #else { "Dummy test", dummy_test } #endif From 6cbaaf687b75aad4a99e8446f0905bde081c72c3 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 13 Jan 2016 17:11:22 +0100 Subject: [PATCH 063/121] Forgot to commit a few things in previous commit --- coreapi/friendlist.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index e78eb9a91..e97832770 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -430,30 +430,41 @@ void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list) { } static void carddav_created(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { - if (cdc && cdc->friend_list->cbs->contact_created_cb) { + if (cdc) { LinphoneFriendList *lfl = cdc->friend_list; lfl->friends = ms_list_append(lfl->friends, linphone_friend_ref(lf)); - cdc->friend_list->cbs->contact_created_cb(lfl, linphone_friend_ref(lf)); + if (cdc->friend_list->cbs->contact_created_cb) { + cdc->friend_list->cbs->contact_created_cb(lfl, linphone_friend_ref(lf)); + } } linphone_friend_unref(lf); } static void carddav_removed(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { - if (cdc && cdc->friend_list->cbs->contact_deleted_cb) { + if (cdc) { LinphoneFriendList *lfl = cdc->friend_list; MSList *elem = ms_list_find(lfl->friends, lf); - lfl->friends = ms_list_remove_link(lfl->friends, elem); - cdc->friend_list->cbs->contact_deleted_cb(lfl, linphone_friend_ref(lf)); + if (elem) { + lfl->friends = ms_list_remove_link(lfl->friends, elem); + } + if (cdc->friend_list->cbs->contact_deleted_cb) { + cdc->friend_list->cbs->contact_deleted_cb(lfl, linphone_friend_ref(lf)); + } } linphone_friend_unref(lf); } +static void carddav_updated(LinphoneCardDavContext *cdc, LinphoneFriend *lf_new, LinphoneFriend *lf_old) { + //TODO +} + void linphone_friend_list_synchronize_friends_from_server(LinphoneFriendList *list) { LinphoneCardDavContext *cdc = linphone_carddav_context_new(list); if (cdc) { cdc->contact_created_cb = carddav_created; cdc->contact_removed_cb = carddav_removed; + cdc->contact_updated_cb = carddav_updated; cdc->sync_done_cb = carddav_done; linphone_carddav_synchronize(cdc); } From bce8c3cc76f071180452f359aac14b5ea5faf8bd Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 14 Jan 2016 15:04:08 +0100 Subject: [PATCH 064/121] Started rework of friend lists management in linphone + database storage of friend lists --- coreapi/carddav.c | 52 ++++++- coreapi/friend.c | 308 +++++++++++++++++++++++++++++--------- coreapi/friendlist.c | 39 +++-- coreapi/friendlist.h | 26 +++- coreapi/linphonecore.c | 97 ++++++++---- coreapi/presence.c | 16 +- coreapi/private.h | 8 +- tester/Makefile.am | 3 +- tester/presence_tester.c | 57 +++---- tester/rcfiles/carddav_rc | 12 ++ tester/vcard_tester.c | 70 +++++---- 11 files changed, 507 insertions(+), 181 deletions(-) create mode 100644 tester/rcfiles/carddav_rc diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 449561e14..40dcca759 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -112,7 +112,6 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * LinphoneFriend *lf2 = (LinphoneFriend *)local_friend->data; if (cdc->contact_updated_cb) { ms_debug("Contact updated: %s", linphone_friend_get_name(lf)); - lf2 = linphone_friend_ref(lf2); cdc->contact_updated_cb(cdc, lf, lf2); } } else { @@ -173,6 +172,7 @@ static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf); const char *uid1 = NULL, *uid2 = NULL; if (!lvc1 || !lvc2) { + if (lvc1) linphone_vcard_free(lvc1); return 1; } uid1 = linphone_vcard_get_uid(lvc1); @@ -187,17 +187,15 @@ static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList *vCards) { if (vCards != NULL && ms_list_size(vCards) > 0) { MSList *friends = cdc->friend_list->friends; + MSList *friends_to_remove = NULL; + while (friends) { LinphoneFriend *lf = (LinphoneFriend *)friends->data; if (lf) { MSList *vCard = ms_list_find_custom(vCards, (int (*)(const void*, const void*))find_matching_vcard, lf); if (!vCard) { - ms_debug("Local friend %s isn't in the remote vCard list, delete it", linphone_friend_get_name(lf)); - if (cdc->contact_removed_cb) { - ms_debug("Contact removed: %s", linphone_friend_get_name(lf)); - lf = linphone_friend_ref(lf); - cdc->contact_removed_cb(cdc, lf); - } + ms_error("Local friend %s isn't in the remote vCard list, delete it", linphone_friend_get_name(lf)); + friends_to_remove = ms_list_append(friends_to_remove, lf); } else { LinphoneCardDavResponse *response = (LinphoneCardDavResponse *)vCard->data; ms_debug("Local friend %s is in the remote vCard list, check eTag", linphone_friend_get_name(lf)); @@ -213,6 +211,18 @@ static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList } friends = ms_list_next(friends); } + while(friends_to_remove) { + LinphoneFriend *lf = (LinphoneFriend *)friends_to_remove->data; + if (lf) { + if (cdc->contact_removed_cb) { + ms_error("Contact removed: %s", linphone_friend_get_name(lf)); + cdc->contact_removed_cb(cdc, lf); + } + } + friends_to_remove = ms_list_next(friends_to_remove); + } + friends_to_remove = ms_list_free(friends_to_remove); + linphone_carddav_pull_vcards(cdc, vCards); } ms_list_free(vCards); @@ -376,7 +386,33 @@ static void process_io_error_from_carddav_request(void *data, const belle_sip_io } static void process_auth_requested_from_carddav_request(void *data, belle_sip_auth_event_t *event) { - //TODO //FIXME: find a way around this + LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data; + LinphoneCardDavContext *cdc = query->context; + const char *realm = belle_sip_auth_event_get_realm(event); + belle_generic_uri_t *uri = belle_generic_uri_parse(query->url); + const char *domain = belle_generic_uri_get_host(uri); + LinphoneCore *lc = cdc->friend_list->lc; + const MSList *auth_infos = linphone_core_get_auth_info_list(lc); + + ms_debug("Looking for auth info for domain %s and realm %s", domain, realm); + while (auth_infos) { + LinphoneAuthInfo *auth_info = (LinphoneAuthInfo *)auth_infos->data; + if (auth_info->domain && strcmp(domain, auth_info->domain) == 0) { + if (!auth_info->realm || strcmp(realm, auth_info->realm) == 0) { + belle_sip_auth_event_set_username(event, auth_info->username); + belle_sip_auth_event_set_passwd(event, auth_info->passwd); + belle_sip_auth_event_set_ha1(event, auth_info->ha1); + break; + } + } + auth_infos = ms_list_next(auth_infos); + } + + if (!auth_infos) { + ms_error("Authentication requested during CardDAV request sending, and username/password weren't provided"); + linphone_carddav_sync_done(query->context, FALSE, "Authentication requested during CardDAV request sending, and username/password weren't provided"); + linphone_carddav_query_free(query); + } } static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { diff --git a/coreapi/friend.c b/coreapi/friend.c index bacab20f0..fe015a10b 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -521,7 +521,7 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc) { fr->inc_subscribe_pending = FALSE; } if (fr->lc) { - linphone_friend_list_update_subscriptions(fr->lc->friendlist, NULL, linphone_core_should_subscribe_friends_only_when_registered(fr->lc)); + linphone_friend_list_update_subscriptions(fr->friend_list, NULL, linphone_core_should_subscribe_friends_only_when_registered(fr->lc)); } ms_debug("linphone_friend_apply() done."); lc->bl_refresh=TRUE; @@ -561,7 +561,7 @@ LinphoneFriend * linphone_core_create_friend_with_address(LinphoneCore *lc, cons } void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) { - if ((lc->friendlist == NULL) || (linphone_friend_list_add_friend(lc->friendlist, lf) != LinphoneFriendListOK)) return; + if ((lc->friends_lists == NULL) || (linphone_friend_list_add_friend(linphone_core_get_default_friend_list(lc), lf) != LinphoneFriendListOK)) return; if (ms_list_find(lc->subscribers, lf)) { /*if this friend was in the pending subscriber list, now remove it from this list*/ lc->subscribers = ms_list_remove(lc->subscribers, lf); @@ -574,14 +574,19 @@ void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) { } void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend *lf) { - if (linphone_friend_list_remove_friend(lc->friendlist, lf) == LinphoneFriendListNonExistentFriend) { - ms_error("linphone_core_remove_friend(): friend [%p] is not part of core's list.", lf); + if (lf && lf->friend_list) { + if (linphone_friend_list_remove_friend(lf->friend_list, lf) == LinphoneFriendListNonExistentFriend) { + ms_error("linphone_core_remove_friend(): friend [%p] is not part of core's list.", lf); + } } } -void linphone_core_update_friends_subscriptions(LinphoneCore *lc, LinphoneProxyConfig *cfg, bool_t only_when_registered){ - if (lc->friendlist != NULL) { - linphone_friend_list_update_subscriptions(lc->friendlist, cfg, only_when_registered); +void linphone_core_update_friends_subscriptions(LinphoneCore *lc, LinphoneProxyConfig *cfg, bool_t only_when_registered) { + MSList *lists = lc->friends_lists; + while (lists) { + LinphoneFriendList *list = (LinphoneFriendList *)lists->data; + linphone_friend_list_update_subscriptions(list, cfg, only_when_registered); + lists = ms_list_next(lists); } } @@ -589,40 +594,49 @@ bool_t linphone_core_should_subscribe_friends_only_when_registered(const Linphon return lp_config_get_int(lc->config,"sip","subscribe_presence_only_when_registered",1); } -void linphone_core_send_initial_subscribes(LinphoneCore *lc){ +void linphone_core_send_initial_subscribes(LinphoneCore *lc) { + MSList *lists = lc->friends_lists; bool_t proxy_config_for_rls_presence_uri_domain = FALSE; LinphoneAddress *rls_address = NULL; const MSList *elem; if (lc->initial_subscribes_sent) return; lc->initial_subscribes_sent=TRUE; - if (lc->friendlist->rls_uri != NULL) { - rls_address = linphone_core_create_address(lc, lc->friendlist->rls_uri); - } - if (rls_address != NULL) { - const char *rls_domain = linphone_address_get_domain(rls_address); - if (rls_domain != NULL) { - for (elem = linphone_core_get_proxy_config_list(lc); elem != NULL; elem = elem->next) { - LinphoneProxyConfig *cfg = (LinphoneProxyConfig *)elem->data; - const char *proxy_domain = linphone_proxy_config_get_domain(cfg); - if (strcmp(rls_domain, proxy_domain) == 0) { - proxy_config_for_rls_presence_uri_domain = TRUE; - break; + while (lists) { + LinphoneFriendList *list = (LinphoneFriendList *)lists->data; + if (list->rls_uri != NULL) { + rls_address = linphone_core_create_address(lc, list->rls_uri); + if (rls_address != NULL) { + const char *rls_domain = linphone_address_get_domain(rls_address); + if (rls_domain != NULL) { + for (elem = linphone_core_get_proxy_config_list(lc); elem != NULL; elem = elem->next) { + LinphoneProxyConfig *cfg = (LinphoneProxyConfig *)elem->data; + const char *proxy_domain = linphone_proxy_config_get_domain(cfg); + if (strcmp(rls_domain, proxy_domain) == 0) { + proxy_config_for_rls_presence_uri_domain = TRUE; + break; + } + } } + linphone_address_unref(rls_address); + } + if (proxy_config_for_rls_presence_uri_domain == TRUE) { + ms_message("Presence list activated so do not send initial subscribes it will be done when registered"); + } else { + linphone_core_update_friends_subscriptions(lc,NULL,linphone_core_should_subscribe_friends_only_when_registered(lc)); } } - linphone_address_unref(rls_address); - } - if (proxy_config_for_rls_presence_uri_domain == TRUE) { - ms_message("Presence list activated so do not send initial subscribes it will be done when registered"); - } else { - linphone_core_update_friends_subscriptions(lc,NULL,linphone_core_should_subscribe_friends_only_when_registered(lc)); + lists = ms_list_next(lists); } } -void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc){ - if (lc->friendlist != NULL) - linphone_friend_list_invalidate_subscriptions(lc->friendlist); +void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc) { + MSList *lists = lc->friends_lists; + while (lists) { + LinphoneFriendList *list = (LinphoneFriendList *)lists->data; + linphone_friend_list_invalidate_subscriptions(list); + lists = ms_list_next(lists); + } lc->initial_subscribes_sent=FALSE; } @@ -643,16 +657,37 @@ const char *linphone_friend_get_ref_key(const LinphoneFriend *lf){ return lf->refkey; } -LinphoneFriend *linphone_core_find_friend(const LinphoneCore *lc, const LinphoneAddress *addr){ - return linphone_friend_list_find_friend_by_address(lc->friendlist, addr); +LinphoneFriend *linphone_core_find_friend(const LinphoneCore *lc, const LinphoneAddress *addr) { + MSList *lists = lc->friends_lists; + LinphoneFriend *lf = NULL; + while (lists && !lf) { + LinphoneFriendList *list = (LinphoneFriendList *)lists->data; + lf = linphone_friend_list_find_friend_by_address(list, addr); + lists = ms_list_next(lists); + } + return lf; } -LinphoneFriend *linphone_core_get_friend_by_address(const LinphoneCore *lc, const char *uri){ - return linphone_friend_list_find_friend_by_uri(lc->friendlist, uri); +LinphoneFriend *linphone_core_get_friend_by_address(const LinphoneCore *lc, const char *uri) { + MSList *lists = lc->friends_lists; + LinphoneFriend *lf = NULL; + while (lists && !lf) { + LinphoneFriendList *list = (LinphoneFriendList *)lists->data; + lf = linphone_friend_list_find_friend_by_uri(list, uri); + lists = ms_list_next(lists); + } + return lf; } -LinphoneFriend *linphone_core_get_friend_by_ref_key(const LinphoneCore *lc, const char *key){ - return linphone_friend_list_find_friend_by_ref_key(lc->friendlist, key); +LinphoneFriend *linphone_core_get_friend_by_ref_key(const LinphoneCore *lc, const char *key) { + MSList *lists = lc->friends_lists; + LinphoneFriend *lf = NULL; + while (lists && !lf) { + LinphoneFriendList *list = (LinphoneFriendList *)lists->data; + lf = linphone_friend_list_find_friend_by_ref_key(list, key); + lists = ms_list_next(lists); + } + return lf; } #define key_compare(s1,s2) strcmp(s1,s2) @@ -766,7 +801,8 @@ void linphone_core_write_friends_config(LinphoneCore* lc) { if (! linphone_core_ready(lc)) return; /*dont write config when reading it !*/ store_friends = lp_config_get_int(lc->config, "misc", "store_friends", 1); if (store_friends) { - for (elem=lc->friendlist->friends,i=0; elem!=NULL; elem=ms_list_next(elem),i++){ + + for (elem=linphone_core_get_default_friend_list(lc)->friends,i=0; elem!=NULL; elem=ms_list_next(elem),i++){ linphone_friend_write_to_config_file(lc->config,(LinphoneFriend*)elem->data,i); } linphone_friend_write_to_config_file(lc->config,NULL,i); /* set the end */ @@ -893,11 +929,8 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * LinphoneVCard *vcard = (LinphoneVCard *)vcards->data; LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); if (lf) { - if (LinphoneFriendListOK == linphone_friend_list_import_friend(lc->friendlist, lf)) { + if (LinphoneFriendListOK == linphone_friend_list_import_friend(linphone_core_get_default_friend_list(lc), lf)) { lf->lc = lc; -#ifdef FRIENDS_SQL_STORAGE_ENABLED - linphone_core_store_friend_in_db(lc, lf); -#endif count++; } linphone_friend_unref(lf); @@ -965,6 +998,7 @@ static void linphone_create_table(sqlite3* db) { int ret; ret = sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS friends (" "id INTEGER PRIMARY KEY AUTOINCREMENT," + "friend_list_id INTEGER," "sip_uri TEXT NOT NULL," "subscribe_policy INTEGER," "send_subscribe INTEGER," @@ -979,6 +1013,19 @@ static void linphone_create_table(sqlite3* db) { ms_error("Error in creation: %s.\n", errmsg); sqlite3_free(errmsg); } + + ret = sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS friends_lists (" + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "display_name TEXT," + "rls_uri TEXT," + "uri TEXT," + "revision INTEGER" + ");", + 0, 0, &errmsg); + if (ret != SQLITE_OK) { + ms_error("Error in creation: %s.\n", errmsg); + sqlite3_free(errmsg); + } } static void linphone_update_table(sqlite3* db) { @@ -989,7 +1036,7 @@ void linphone_core_friends_storage_init(LinphoneCore *lc) { int ret; const char *errmsg; sqlite3 *db; - const MSList *friends = NULL; + const MSList *friends_lists = NULL; linphone_core_friends_storage_close(lc); @@ -1005,13 +1052,11 @@ void linphone_core_friends_storage_init(LinphoneCore *lc) { linphone_update_table(db); lc->friends_db = db; - friends = linphone_core_fetch_friends_from_db(lc); - while (friends && friends->data) { - LinphoneFriend *lf = friends->data; - linphone_core_add_friend(lc, lf); - linphone_friend_unref(lf); - - friends = ms_list_next(friends); + friends_lists = linphone_core_fetch_friends_lists_from_db(lc); + while (friends_lists) { + LinphoneFriendList *list = (LinphoneFriendList *)friends_lists->data; + linphone_core_add_friend_list(lc, list); + friends_lists = ms_list_next(friends_lists); } } @@ -1024,14 +1069,38 @@ void linphone_core_friends_storage_close(LinphoneCore *lc) { /* DB layout: * | 0 | storage_id - * | 1 | sip_uri - * | 2 | subscribe_policy - * | 3 | send_subscribe - * | 4 | ref_key - * | 5 | vCard - * | 6 | vCard eTag - * | 7 | vCard URL - * | 8 | presence_received + * | 1 | display_name + * | 2 | rls_uri + * | 3 | uri + * | 4 | revision + */ +static int create_friend_list(void *data, int argc, char **argv, char **colName) { + MSList **list = (MSList **)data; + unsigned int storage_id = atoi(argv[0]); + LinphoneFriendList *lfl = linphone_core_create_friend_list(NULL); + + lfl->storage_id = storage_id; + linphone_friend_list_set_display_name(lfl, argv[1]); + linphone_friend_list_set_rls_uri(lfl, argv[2]); + linphone_friend_list_set_uri(lfl, argv[3]); + lfl->revision = atoi(argv[4]); + + *list = ms_list_append(*list, linphone_friend_list_ref(lfl)); + linphone_friend_list_unref(lfl); + return 0; +} + +/* DB layout: + * | 0 | storage_id + * | 1 | friend_list_id + * | 2 | sip_uri + * | 3 | subscribe_policy + * | 4 | send_subscribe + * | 5 | ref_key + * | 6 | vCard + * | 7 | vCard eTag + * | 8 | vCard URL + * | 9 | presence_received */ static int create_friend(void *data, int argc, char **argv, char **colName) { MSList **list = (MSList **)data; @@ -1039,22 +1108,22 @@ static int create_friend(void *data, int argc, char **argv, char **colName) { LinphoneVCard *vcard = NULL; unsigned int storage_id = atoi(argv[0]); - vcard = linphone_vcard_new_from_vcard4_buffer(argv[5]); + vcard = linphone_vcard_new_from_vcard4_buffer(argv[6]); if (vcard) { - linphone_vcard_set_etag(vcard, argv[6]); - linphone_vcard_set_url(vcard, argv[7]); + linphone_vcard_set_etag(vcard, argv[7]); + linphone_vcard_set_url(vcard, argv[8]); lf = linphone_friend_new_from_vcard(vcard); } if (!lf) { - LinphoneAddress *addr = linphone_address_new(argv[1]); + LinphoneAddress *addr = linphone_address_new(argv[2]); lf = linphone_friend_new(); linphone_friend_set_address(lf, addr); linphone_address_unref(addr); } - linphone_friend_set_inc_subscribe_policy(lf, atoi(argv[2])); - linphone_friend_send_subscribe(lf, atoi(argv[3])); - linphone_friend_set_ref_key(lf, ms_strdup(argv[4])); - lf->presence_received = atoi(argv[8]); + linphone_friend_set_inc_subscribe_policy(lf, atoi(argv[3])); + linphone_friend_send_subscribe(lf, atoi(argv[4])); + linphone_friend_set_ref_key(lf, ms_strdup(argv[5])); + lf->presence_received = atoi(argv[9]); lf->storage_id = storage_id; *list = ms_list_append(*list, linphone_friend_ref(lf)); @@ -1073,6 +1142,17 @@ static int linphone_sql_request_friend(sqlite3* db, const char *stmt, MSList **l return ret; } +static int linphone_sql_request_friends_list(sqlite3* db, const char *stmt, MSList **list) { + char* errmsg = NULL; + int ret; + ret = sqlite3_exec(db, stmt, create_friend_list, list, &errmsg); + if (ret != SQLITE_OK) { + ms_error("linphone_sql_request: statement %s -> error sqlite3_exec(): %s.", stmt, errmsg); + sqlite3_free(errmsg); + } + return ret; +} + static int linphone_sql_request_generic(sqlite3* db, const char *stmt) { char* errmsg = NULL; int ret; @@ -1093,9 +1173,15 @@ void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) { if (!store_friends) { return; } + + if (lf->friend_list->storage_id == 0) { + ms_warning("Trying to add a friend in db, but friend list isn't, let's do that first"); + linphone_core_store_friends_list_in_db(lc, lf->friend_list); + } if (lf->storage_id > 0) { - buf = sqlite3_mprintf("UPDATE friends SET sip_uri=%Q,subscribe_policy=%i,send_subscribe=%i,ref_key=%Q,vCard=%Q,vCard_etag=%Q,vCard_url=%Q,presence_received=%i WHERE (id = %i);", + buf = sqlite3_mprintf("UPDATE friends SET friend_list_id=%i,sip_uri=%Q,subscribe_policy=%i,send_subscribe=%i,ref_key=%Q,vCard=%Q,vCard_etag=%Q,vCard_url=%Q,presence_received=%i WHERE (id = %i);", + lf->friend_list->storage_id, linphone_address_as_string(linphone_friend_get_address(lf)), lf->pol, lf->subscribe, @@ -1107,7 +1193,8 @@ void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) { lf->storage_id ); } else { - buf = sqlite3_mprintf("INSERT INTO friends VALUES(NULL,%Q,%i,%i,%Q,%Q,%Q,%Q,%i);", + buf = sqlite3_mprintf("INSERT INTO friends VALUES(NULL,%i,%Q,%i,%i,%Q,%Q,%Q,%Q,%i);", + lf->friend_list->storage_id, linphone_address_as_string(linphone_friend_get_address(lf)), lf->pol, lf->subscribe, @@ -1127,6 +1214,40 @@ void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) { } } +void linphone_core_store_friends_list_in_db(LinphoneCore *lc, LinphoneFriendList *list) { + if (lc && lc->friends_db) { + char *buf; + int store_friends = lp_config_get_int(lc->config, "misc", "store_friends", 1); + + if (!store_friends) { + return; + } + + if (list->storage_id > 0) { + buf = sqlite3_mprintf("UPDATE friends_lists SET display_name=%Q,rls_uri=%Q,uri=%Q,revision=%i WHERE (id = %i);", + list->display_name, + list->rls_uri, + list->uri, + list->revision, + list->storage_id + ); + } else { + buf = sqlite3_mprintf("INSERT INTO friends_lists VALUES(NULL,%Q,%Q,%Q,%i);", + list->display_name, + list->rls_uri, + list->uri, + list->revision + ); + } + linphone_sql_request_generic(lc->friends_db, buf); + sqlite3_free(buf); + + if (list->storage_id == 0) { + list->storage_id = sqlite3_last_insert_rowid(lc->friends_db); + } + } +} + void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf) { if (lc && lc->friends_db) { char *buf; @@ -1143,7 +1264,44 @@ void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf) { } } -MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) { +void linphone_core_remove_friends_list_from_db(LinphoneCore *lc, LinphoneFriendList *list) { + if (lc && lc->friends_db) { + char *buf; + if (list->storage_id == 0) { + ms_error("Friends list doesn't have a storage_id !"); + return; + } + + buf = sqlite3_mprintf("DELETE FROM friends_lists WHERE id = %i", list->storage_id); + linphone_sql_request_generic(lc->friends_db, buf); + sqlite3_free(buf); + + list->storage_id = 0; + } +} + +MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc, LinphoneFriendList *list) { + char *buf; + uint64_t begin,end; + MSList *result = NULL; + + if (!lc || lc->friends_db == NULL || list == NULL) { + ms_warning("Either lc (or list) is NULL or friends database wasn't initialized with linphone_core_friends_storage_init() yet"); + return NULL; + } + + buf = sqlite3_mprintf("SELECT * FROM friends WHERE friend_list_id = %i ORDER BY id", list->storage_id); + + begin = ortp_get_cur_time_ms(); + linphone_sql_request_friend(lc->friends_db, buf, &result); + end = ortp_get_cur_time_ms(); + ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin)); + sqlite3_free(buf); + + return result; +} + +MSList* linphone_core_fetch_friends_lists_from_db(LinphoneCore *lc) { char *buf; uint64_t begin,end; MSList *result = NULL; @@ -1153,10 +1311,10 @@ MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) { return NULL; } - buf = sqlite3_mprintf("SELECT * FROM friends ORDER BY id"); + buf = sqlite3_mprintf("SELECT * FROM friends_lists ORDER BY id"); begin = ortp_get_cur_time_ms(); - linphone_sql_request_friend(lc->friends_db, buf, &result); + linphone_sql_request_friends_list(lc->friends_db, buf, &result); end = ortp_get_cur_time_ms(); ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin)); sqlite3_free(buf); @@ -1175,10 +1333,20 @@ void linphone_core_friends_storage_close(LinphoneCore *lc) { void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) { } +void linphone_core_store_friends_list_in_db(LinphoneCore *lc, LinphoneFriendList *list) { +} + void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf) { } -MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) { +void linphone_core_remove_friends_list_from_db(LinphoneCore *lc, LinphoneFriendList *list) { +} + +MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc, LinphoneFriendList *list) { + return NULL; +} + +MSList* linphone_core_fetch_friends_lists_from_db(LinphoneCore *lc) { return NULL; } diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index e97832770..3ce918215 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -280,8 +280,8 @@ static void linphone_friend_list_destroy(LinphoneFriendList *list) { if (list->event != NULL) linphone_event_unref(list->event); if (list->uri != NULL) ms_free(list->uri); if (list->cbs) linphone_friend_list_cbs_unref(list->cbs); - list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))linphone_friend_unref); - list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))_linphone_friend_release); + list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref); + list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release); } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriendList); @@ -316,9 +316,9 @@ void _linphone_friend_list_release(LinphoneFriendList *list){ linphone_friend_list_cbs_unref(list->cbs); list->cbs = NULL; } + list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref); list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release); - list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))_linphone_friend_release); - belle_sip_object_unref(list); + linphone_friend_list_unref(list); } void linphone_friend_list_unref(LinphoneFriendList *list) { @@ -361,6 +361,23 @@ void linphone_friend_list_set_rls_uri(LinphoneFriendList *list, const char *rls_ } } +LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf) { + if (lf->uri == NULL || lf->friend_list) { + if (!lf->uri) + ms_error("linphone_friend_list_add_friend(): invalid friend, no sip uri"); + if (lf->friend_list) + ms_error("linphone_friend_list_add_friend(): invalid friend, already in list"); + return LinphoneFriendListInvalidFriend; + } + list->friends = ms_list_append(list->friends, linphone_friend_ref(lf)); + lf->friend_list = list; + lf->lc = list->lc; +#ifdef FRIENDS_SQL_STORAGE_ENABLED + linphone_core_store_friend_in_db(lf->lc, lf); +#endif + return LinphoneFriendListOK; +} + LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf) { if (lf->uri == NULL || lf->friend_list) { if (!lf->uri) @@ -386,6 +403,10 @@ LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList * list->friends = ms_list_append(list->friends, linphone_friend_ref(lf)); list->dirty_friends_to_update = ms_list_append(list->dirty_friends_to_update, linphone_friend_ref(lf)); lf->friend_list = list; + lf->lc = list->lc; +#ifdef FRIENDS_SQL_STORAGE_ENABLED + linphone_core_store_friend_in_db(lf->lc, lf); +#endif return LinphoneFriendListOK; } @@ -425,19 +446,18 @@ void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list) { } dirty_friends = ms_list_next(dirty_friends); } + list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref); } - list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref); } static void carddav_created(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { if (cdc) { LinphoneFriendList *lfl = cdc->friend_list; - lfl->friends = ms_list_append(lfl->friends, linphone_friend_ref(lf)); + _linphone_friend_list_add_friend(lfl, lf); if (cdc->friend_list->cbs->contact_created_cb) { - cdc->friend_list->cbs->contact_created_cb(lfl, linphone_friend_ref(lf)); + cdc->friend_list->cbs->contact_created_cb(lfl, lf); } } - linphone_friend_unref(lf); } static void carddav_removed(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { @@ -448,10 +468,9 @@ static void carddav_removed(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { lfl->friends = ms_list_remove_link(lfl->friends, elem); } if (cdc->friend_list->cbs->contact_deleted_cb) { - cdc->friend_list->cbs->contact_deleted_cb(lfl, linphone_friend_ref(lf)); + cdc->friend_list->cbs->contact_deleted_cb(lfl, lf); } } - linphone_friend_unref(lf); } static void carddav_updated(LinphoneCardDavContext *cdc, LinphoneFriend *lf_new, LinphoneFriend *lf_old) { diff --git a/coreapi/friendlist.h b/coreapi/friendlist.h index 9efe9824b..9f083eabe 100644 --- a/coreapi/friendlist.h +++ b/coreapi/friendlist.h @@ -62,11 +62,32 @@ typedef struct _LinphoneFriendList LinphoneFriendList; LINPHONE_PUBLIC LinphoneFriendList * linphone_core_create_friend_list(LinphoneCore *lc); /** - * Set the friend list. + * Add a friend list. * @param[in] lc LinphoneCore object * @param[in] list LinphoneFriendList object */ -LINPHONE_PUBLIC void linphone_core_set_friend_list(LinphoneCore *lc, LinphoneFriendList *list); +LINPHONE_PUBLIC void linphone_core_add_friend_list(LinphoneCore *lc, LinphoneFriendList *list); + +/** + * Removes a friend list. + * @param[in] lc LinphoneCore object + * @param[in] list LinphoneFriendList object + */ +LINPHONE_PUBLIC void linphone_core_remove_friend_list(LinphoneCore *lc, LinphoneFriendList *list); + +/** + * Retrieves the list of LinphoneFriendList from the core. + * @param[in] lc LinphoneCore object + * @return \mslist{LinphoneFriendList} a list of LinphoneFriendList + */ +LINPHONE_PUBLIC const MSList * linphone_core_get_friends_lists(const LinphoneCore *lc); + +/** + * Retrieves the first list of LinphoneFriend from the core. + * @param[in] lc LinphoneCore object + * @return the first LinphoneFriendList object or NULL + */ +LINPHONE_PUBLIC LinphoneFriendList * linphone_core_get_default_friend_list(const LinphoneCore *lc); /** * Acquire a reference to the friend list. @@ -130,6 +151,7 @@ LINPHONE_PUBLIC void linphone_friend_list_set_rls_uri(LinphoneFriendList *list, * @return LinphoneFriendListOK if successfully added, LinphoneFriendListInvalidFriend if the friend is not valid. **/ LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *afriend); +LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *afriend); /** * Remove a friend from a friend list. diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index bba34d427..d27384655 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1679,7 +1679,7 @@ static void linphone_core_register_default_codecs(LinphoneCore *lc){ static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *notified_event, const LinphoneContent *body) { if (strcmp(notified_event, "Presence") == 0) { - linphone_friend_list_notify_presence_received(lc->friendlist, lev, body); + linphone_friend_list_notify_presence_received(linphone_core_get_default_friend_list(lc), lev, body); } } @@ -1687,13 +1687,23 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab const char *remote_provisioning_uri = NULL; LinphoneCoreVTable* local_vtable= linphone_core_v_table_new(); LinphoneCoreVTable *internal_vtable = linphone_core_v_table_new(); + LinphoneFriendList *list = NULL; + const char *rls_uri = NULL; ms_message("Initializing LinphoneCore %s", linphone_core_get_version()); lc->config=lp_config_ref(config); lc->data=userdata; lc->ringstream_autorelease=TRUE; - linphone_core_set_friend_list(lc, NULL); + + list = linphone_core_create_friend_list(lc); + rls_uri = lp_config_get_string(lc->config, "sip", "rls_uri", NULL); + if (rls_uri && lp_config_get_int(lc->config, "sip", "use_rls_presence", 0)) { + linphone_friend_list_set_rls_uri(list, rls_uri); + } + linphone_core_add_friend_list(lc, list); + linphone_friend_list_unref(list); + linphone_task_list_init(&lc->hooks); internal_vtable->notify_received = linphone_core_internal_notify_received; @@ -1930,24 +1940,47 @@ bool_t linphone_core_generic_confort_noise_enabled(const LinphoneCore *lc){ return lp_config_get_int(lc->config, "misc", "use_cn", FALSE); } -const MSList * linphone_core_get_friend_list(const LinphoneCore *lc) -{ - return lc->friendlist->friends; +const MSList* linphone_core_get_friend_list(const LinphoneCore *lc) { + if (lc->friends_lists && lc->friends_lists->data) { + LinphoneFriendList *list = (LinphoneFriendList *)lc->friends_lists->data; + return list->friends; + } + return NULL; } -void linphone_core_set_friend_list(LinphoneCore *lc, LinphoneFriendList *list) { - if (lc->friendlist != NULL) { - linphone_friend_list_unref(lc->friendlist); - lc->friendlist = NULL; +const MSList* linphone_core_get_friends_lists(const LinphoneCore *lc) { + return lc->friends_lists; +} + +LinphoneFriendList* linphone_core_get_default_friend_list(const LinphoneCore *lc) { + LinphoneFriendList *list = NULL; + if (!lc->friends_lists) { + return NULL; } - if (list != NULL) { - lc->friendlist = linphone_friend_list_ref(list); - } else { - const char *rls_uri = NULL; - lc->friendlist = linphone_core_create_friend_list(lc); - rls_uri = lp_config_get_string(lc->config, "sip", "rls_uri", NULL); - if (rls_uri && lp_config_get_int(lc->config, "sip", "use_rls_presence", 0)) - linphone_friend_list_set_rls_uri(lc->friendlist, rls_uri); + list = (LinphoneFriendList *)lc->friends_lists->data; + return list; +} + +void linphone_core_remove_friend_list(LinphoneCore *lc, LinphoneFriendList *list) { + MSList *elem = ms_list_find(lc->friends_lists, list); + if (elem == NULL) return; + list->lc = NULL; + linphone_friend_list_unref(list); + lc->friends_lists = ms_list_remove_link(lc->friends_lists, elem); +#ifdef FRIENDS_SQL_STORAGE_ENABLED + linphone_core_remove_friends_list_from_db(lc, list); +#endif +} + +void linphone_core_add_friend_list(LinphoneCore *lc, LinphoneFriendList *list) { + if (list) { + if (!list->lc) { + list->lc = lc; + } + lc->friends_lists = ms_list_append(lc->friends_lists, linphone_friend_list_ref(list)); +#ifdef FRIENDS_SQL_STORAGE_ENABLED + linphone_core_store_friends_list_in_db(lc, list); +#endif } } @@ -2733,11 +2766,15 @@ void linphone_core_iterate(LinphoneCore *lc){ } if (one_second_elapsed) { + MSList *elem = NULL; if (lp_config_needs_commit(lc->config)) { lp_config_sync(lc->config); } - if (lc->friendlist->dirty_friends_to_update) { - linphone_friend_list_update_dirty_friends(lc->friendlist); + for (elem = lc->friends_lists; elem != NULL; elem = ms_list_next(elem)) { + LinphoneFriendList *list = (LinphoneFriendList *)elem->data; + if (list->dirty_friends_to_update) { + linphone_friend_list_update_dirty_friends(list); + } } } @@ -6354,10 +6391,14 @@ static void codecs_config_uninit(LinphoneCore *lc) void ui_config_uninit(LinphoneCore* lc) { + MSList *elem = NULL; ms_message("Destroying friends."); - _linphone_friend_list_release(lc->friendlist); - lc->friendlist = NULL; - if (lc->subscribers){ + for (elem = lc->friends_lists; elem != NULL; elem = ms_list_next(elem)) { + LinphoneFriendList *list = (LinphoneFriendList *)elem->data; + _linphone_friend_list_release(list); + } + lc->friends_lists = NULL; + if (lc->subscribers) { lc->subscribers = ms_list_free_with_data(lc->subscribers, (void (*)(void *))_linphone_friend_release); } if (lc->presence_model) { @@ -6385,18 +6426,22 @@ LpConfig * linphone_core_create_lp_config(LinphoneCore *lc, const char *filename static void linphone_core_uninit(LinphoneCore *lc) { + MSList *elem = NULL; linphone_task_list_free(&lc->hooks); lc->video_conf.show_local = FALSE; - while(lc->calls) - { + while(lc->calls) { LinphoneCall *the_call = lc->calls->data; linphone_core_terminate_call(lc,the_call); linphone_core_iterate(lc); ms_usleep(50000); } - linphone_friend_list_close_subscriptions(lc->friendlist); + for (elem = lc->friends_lists; elem != NULL; elem = ms_list_next(elem)) { + LinphoneFriendList *list = (LinphoneFriendList *)elem->data; + linphone_friend_list_close_subscriptions(list); + } + lc->chatrooms = ms_list_free_with_data(lc->chatrooms, (MSIterateFunc)linphone_chat_room_release); linphone_core_set_state(lc,LinphoneGlobalShutdown,"Shutting down"); @@ -6455,10 +6500,12 @@ static void linphone_core_uninit(LinphoneCore *lc) if (lc->ringtoneplayer) { linphone_ringtoneplayer_destroy(lc->ringtoneplayer); } + linphone_core_free_payload_types(lc); if (lc->supported_formats) ms_free(lc->supported_formats); linphone_core_message_storage_close(lc); linphone_core_call_log_storage_close(lc); + linphone_core_friends_storage_close(lc); ms_exit(); linphone_core_set_state(lc,LinphoneGlobalOff,"Off"); linphone_core_deactivate_log_serialization_if_needed(); diff --git a/coreapi/presence.c b/coreapi/presence.c index cec2b1547..4e98ab028 100644 --- a/coreapi/presence.c +++ b/coreapi/presence.c @@ -1469,7 +1469,7 @@ void linphone_core_notify_all_friends(LinphoneCore *lc, LinphonePresenceModel *p char *activity_str = linphone_presence_activity_to_string(activity); ms_message("Notifying all friends that we are [%s]", activity_str); if (activity_str != NULL) ms_free(activity_str); - linphone_friend_list_notify_presence(lc->friendlist, presence); + linphone_friend_list_notify_presence(linphone_core_get_default_friend_list(lc), presence); } void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){ @@ -1483,8 +1483,8 @@ void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){ ms_message("Receiving new subscription from %s.",from); /* check if we answer to this subscription */ - if (lc->friendlist != NULL) { - lf = linphone_friend_list_find_friend_by_address(lc->friendlist, uri); + if (linphone_core_get_default_friend_list(lc) != NULL) { + lf = linphone_friend_list_find_friend_by_address(linphone_core_get_default_friend_list(lc), uri); } if (lf!=NULL){ linphone_friend_add_incoming_subscription(lf, op); @@ -1854,11 +1854,11 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, Sa LinphoneAddress *friend=NULL; LinphonePresenceModel *presence = model ? (LinphonePresenceModel *)model:linphone_presence_model_new_with_activity(LinphonePresenceActivityOffline, NULL); - if (lc->friendlist != NULL) - lf=linphone_friend_list_find_friend_by_out_subscribe(lc->friendlist,op); + if (linphone_core_get_default_friend_list(lc) != NULL) + lf=linphone_friend_list_find_friend_by_out_subscribe(linphone_core_get_default_friend_list(lc), op); if (lf==NULL && lp_config_get_int(lc->config,"sip","allow_out_of_subscribe_presence",0)){ const SalAddress *addr=sal_op_get_from_address(op); - lf = linphone_friend_list_find_friend_by_address(lc->friendlist, (LinphoneAddress *)addr); + lf = linphone_friend_list_find_friend_by_address(linphone_core_get_default_friend_list(lc), (LinphoneAddress *)addr); } if (lf!=NULL){ LinphonePresenceActivity *activity = NULL; @@ -1904,8 +1904,8 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, Sa void linphone_subscription_closed(LinphoneCore *lc, SalOp *op){ LinphoneFriend *lf = NULL; - if (lc->friendlist != NULL) - lf=linphone_friend_list_find_friend_by_inc_subscribe(lc->friendlist,op); + if (linphone_core_get_default_friend_list(lc) != NULL) + lf = linphone_friend_list_find_friend_by_inc_subscribe(linphone_core_get_default_friend_list(lc), op); if (lf!=NULL){ /*this will release the op*/ diff --git a/coreapi/private.h b/coreapi/private.h index e778bc8f9..86555edfd 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -420,8 +420,12 @@ void linphone_core_friends_storage_init(LinphoneCore *lc); void linphone_core_friends_storage_close(LinphoneCore *lc); void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf); void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf); -MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc); +void linphone_core_store_friends_list_in_db(LinphoneCore *lc, LinphoneFriendList *list); +void linphone_core_remove_friends_list_from_db(LinphoneCore *lc, LinphoneFriendList *list); +MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc, LinphoneFriendList *list); +MSList* linphone_core_fetch_friends_lists_from_db(LinphoneCore *lc); LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf); +LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf); int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, socklen_t *socklen, int default_port); @@ -897,7 +901,7 @@ struct _LinphoneCore ui_config_t ui_conf; autoreplier_config_t autoreplier_conf; LinphoneProxyConfig *default_proxy; - LinphoneFriendList *friendlist; + MSList *friends_lists; MSList *auth_info; struct _RingStream *ringstream; time_t dmfs_playing_start_time; diff --git a/tester/Makefile.am b/tester/Makefile.am index d2da519a5..ec46807a9 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -69,7 +69,8 @@ RCFILES = \ rcfiles/stun_rc\ rcfiles/upnp_rc\ rcfiles/zero_length_params_rc\ - rcfiles/friends_rc + rcfiles/friends_rc\ + rcfiles/carddav_rc IMAGE_FILES = images/nowebcamCIF.jpg diff --git a/tester/presence_tester.c b/tester/presence_tester.c index f0fa5ed14..fabab6df9 100644 --- a/tester/presence_tester.c +++ b/tester/presence_tester.c @@ -200,6 +200,7 @@ static void subscribe_failure_handle_by_app(void) { sal_set_recv_error(marie->lc->sal, 1); lf = linphone_core_get_friend_by_address(marie->lc,lf_identity); + BC_ASSERT_PTR_NOT_NULL_FATAL(lf); linphone_friend_edit(lf); linphone_friend_enable_subscribes(lf,FALSE); /*disable subscription*/ linphone_friend_done(lf); @@ -600,7 +601,8 @@ static void test_presence_list(void) { linphone_friend_list_add_friend(lfl, lf); lf = linphone_core_create_friend_with_address(laure->lc, "sip:michelle@sip.inexistentdomain.com"); linphone_friend_list_add_friend(lfl, lf); - linphone_core_set_friend_list(laure->lc, lfl); + linphone_core_remove_friend_list(laure->lc, linphone_core_get_default_friend_list(laure->lc)); + linphone_core_add_friend_list(laure->lc, lfl); linphone_friend_list_unref(lfl); linphone_core_set_presence_model(laure->lc, linphone_core_create_presence_model_with_activity(laure->lc, LinphonePresenceActivityOnline, NULL)); @@ -610,16 +612,16 @@ static void test_presence_list(void) { wait_for_list(lcs, &laure->stat.number_of_NotifyPresenceReceived, 2, 2000); BC_ASSERT_EQUAL(laure->stat.number_of_NotifyPresenceReceived, 2, int, "%d"); - BC_ASSERT_EQUAL(laure->lc->friendlist->expected_notification_version, 1, int, "%d"); - lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, marie_identity); + BC_ASSERT_EQUAL(linphone_core_get_default_friend_list(laure->lc)->expected_notification_version, 1, int, "%d"); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), marie_identity); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusBusy, int, "%d"); BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d"); BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d"); - lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusVacation, int, "%d"); BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d"); BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d"); - lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, "sip:michelle@sip.inexistentdomain.com"); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), "sip:michelle@sip.inexistentdomain.com"); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d"); BC_ASSERT_EQUAL(lf->presence_received, FALSE, int, "%d"); BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d"); @@ -628,14 +630,15 @@ static void test_presence_list(void) { linphone_friend_list_set_rls_uri(lfl, rls_uri); lf = linphone_core_create_friend_with_address(marie->lc, laure_identity); linphone_friend_list_add_friend(lfl, lf); - linphone_core_set_friend_list(marie->lc, lfl); + linphone_core_remove_friend_list(marie->lc, linphone_core_get_default_friend_list(marie->lc)); + linphone_core_add_friend_list(marie->lc, lfl); linphone_friend_list_unref(lfl); - linphone_friend_list_update_subscriptions(marie->lc->friendlist, NULL, FALSE); + linphone_friend_list_update_subscriptions(linphone_core_get_default_friend_list(marie->lc), NULL, FALSE); wait_for_list(lcs, &marie->stat.number_of_NotifyPresenceReceived, 1, 2000); BC_ASSERT_EQUAL(marie->stat.number_of_NotifyPresenceReceived, 1, int, "%d"); - BC_ASSERT_EQUAL(marie->lc->friendlist->expected_notification_version, 1, int, "%d"); - lf = linphone_friend_list_find_friend_by_uri(marie->lc->friendlist, laure_identity); + BC_ASSERT_EQUAL(linphone_core_get_default_friend_list(marie->lc)->expected_notification_version, 1, int, "%d"); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(marie->lc), laure_identity); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnline, int, "%d"); BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d"); BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d"); @@ -644,14 +647,15 @@ static void test_presence_list(void) { linphone_friend_list_set_rls_uri(lfl, rls_uri); lf = linphone_core_create_friend_with_address(pauline->lc, marie_identity); linphone_friend_list_add_friend(lfl, lf); - linphone_core_set_friend_list(pauline->lc, lfl); + linphone_core_remove_friend_list(pauline->lc, linphone_core_get_default_friend_list(pauline->lc)); + linphone_core_add_friend_list(pauline->lc, lfl); linphone_friend_list_unref(lfl); - linphone_friend_list_update_subscriptions(pauline->lc->friendlist, NULL, FALSE); + linphone_friend_list_update_subscriptions(linphone_core_get_default_friend_list(pauline->lc), NULL, FALSE); wait_for_list(lcs, &pauline->stat.number_of_NotifyPresenceReceived, 1, 2000); BC_ASSERT_EQUAL(pauline->stat.number_of_NotifyPresenceReceived, 1, int, "%d"); - BC_ASSERT_EQUAL(pauline->lc->friendlist->expected_notification_version, 1, int, "%d"); - lf = linphone_friend_list_find_friend_by_uri(pauline->lc->friendlist, marie_identity); + BC_ASSERT_EQUAL(linphone_core_get_default_friend_list(pauline->lc)->expected_notification_version, 1, int, "%d"); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(pauline->lc), marie_identity); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusBusy, int, "%d"); BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d"); BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d"); @@ -662,14 +666,14 @@ static void test_presence_list(void) { /* The number of PresenceReceived events can be 3 or 4 here. TODO: ideally it should always be 3. */ BC_ASSERT_GREATER(laure->stat.number_of_NotifyPresenceReceived, 3, int, "%d"); BC_ASSERT_LOWER(laure->stat.number_of_NotifyPresenceReceived, 4, int, "%d"); - BC_ASSERT_EQUAL(laure->lc->friendlist->expected_notification_version, 2, int, "%d"); - lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, marie_identity); + BC_ASSERT_EQUAL(linphone_core_get_default_friend_list(laure->lc)->expected_notification_version, 2, int, "%d"); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), marie_identity); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnThePhone, int, "%d"); wait_for_list(lcs, &pauline->stat.number_of_NotifyPresenceReceived, 2, 2000); BC_ASSERT_EQUAL(pauline->stat.number_of_NotifyPresenceReceived, 2, int, "%d"); - BC_ASSERT_EQUAL(pauline->lc->friendlist->expected_notification_version, 2, int, "%d"); - lf = linphone_friend_list_find_friend_by_uri(pauline->lc->friendlist, marie_identity); + BC_ASSERT_EQUAL(linphone_core_get_default_friend_list(pauline->lc)->expected_notification_version, 2, int, "%d"); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(pauline->lc), marie_identity); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnThePhone, int, "%d"); enable_publish(laure, FALSE); @@ -678,14 +682,14 @@ static void test_presence_list(void) { wait_for_list(lcs, &dummy, 1, 2000); /* Wait a little bit for the presence notifications. TODO: Wait for the correct number of PresenceReceived events. */ - lf = linphone_friend_list_find_friend_by_uri(pauline->lc->friendlist, marie_identity); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(pauline->lc), marie_identity); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d"); - lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d"); - lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, marie_identity); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), marie_identity); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d"); - lf = linphone_friend_list_find_friend_by_uri(marie->lc->friendlist, laure_identity); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(marie->lc), laure_identity); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d"); linphone_core_manager_destroy(laure); @@ -713,10 +717,11 @@ static void test_presence_list_subscribe_before_publish(void) { linphone_friend_list_add_friend(lfl, lf); lf = linphone_core_create_friend_with_address(laure->lc, "sip:michelle@sip.inexistentdomain.com"); linphone_friend_list_add_friend(lfl, lf); - linphone_core_set_friend_list(laure->lc, lfl); + linphone_core_remove_friend_list(laure->lc, linphone_core_get_default_friend_list(laure->lc)); + linphone_core_add_friend_list(laure->lc, lfl); linphone_friend_list_unref(lfl); linphone_core_set_presence_model(laure->lc, linphone_core_create_presence_model_with_activity(laure->lc, LinphonePresenceActivityOnline, NULL)); - linphone_friend_list_update_subscriptions(laure->lc->friendlist, NULL, FALSE); + linphone_friend_list_update_subscriptions(linphone_core_get_default_friend_list(laure->lc), NULL, FALSE); lcs = ms_list_append(lcs, laure->lc); lcs = ms_list_append(lcs, pauline->lc); @@ -726,12 +731,12 @@ static void test_presence_list_subscribe_before_publish(void) { enable_publish(pauline, TRUE); wait_for_list(lcs, &pauline->stat.number_of_NotifyPresenceReceived, 1, 2000); BC_ASSERT_GREATER(laure->stat.number_of_NotifyPresenceReceived, 1, int, "%d"); - BC_ASSERT_GREATER(laure->lc->friendlist->expected_notification_version, 1, int, "%d"); - lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity); + BC_ASSERT_GREATER(linphone_core_get_default_friend_list(laure->lc)->expected_notification_version, 1, int, "%d"); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusVacation, int, "%d"); BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d"); BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d"); - lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, "sip:michelle@sip.inexistentdomain.com"); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), "sip:michelle@sip.inexistentdomain.com"); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d"); BC_ASSERT_EQUAL(lf->presence_received, FALSE, int, "%d"); BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d"); diff --git a/tester/rcfiles/carddav_rc b/tester/rcfiles/carddav_rc new file mode 100644 index 000000000..b5169b5fd --- /dev/null +++ b/tester/rcfiles/carddav_rc @@ -0,0 +1,12 @@ +[net] +mtu=1300 + +[sip] +ping_with_options=0 +sip_random_port=1 + +[auth_info_0] +domain=192.168.0.230 +username=sylvain +ha1=4747ce2517a985f2fc20234a38f068b6 +realm=SabreDAV \ No newline at end of file diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index e838ef035..3a09bf890 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -36,6 +36,7 @@ static void linphone_vcard_import_export_friends_test(void) { int count = 0; BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); + BC_ASSERT_PTR_NOT_NULL_FATAL(linphone_core_get_default_friend_list(manager->lc)); count = linphone_core_import_friends_from_vcard4_file(manager->lc, import_filepath); BC_ASSERT_EQUAL(count, 3, int, "%d"); friends = linphone_core_get_friend_list(manager->lc); @@ -43,10 +44,11 @@ static void linphone_vcard_import_export_friends_test(void) { linphone_core_export_friends_as_vcard4_file(manager->lc, export_filepath); - linphone_core_set_friend_list(manager->lc, NULL); + linphone_core_remove_friend_list(manager->lc, linphone_core_get_default_friend_list(manager->lc)); friends = linphone_core_get_friend_list(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); + linphone_core_add_friend_list(manager->lc, linphone_core_create_friend_list(manager->lc)); count = linphone_core_import_friends_from_vcard4_file(manager->lc, export_filepath); BC_ASSERT_EQUAL(count, 3, int, "%d"); friends = linphone_core_get_friend_list(manager->lc); @@ -98,7 +100,6 @@ static void friends_if_no_db_set(void) { #ifdef FRIENDS_SQL_STORAGE_ENABLED static void friends_migration(void) { LinphoneCoreManager* manager = linphone_core_manager_new2("friends_rc", FALSE); - LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); const MSList *friends = linphone_core_get_friend_list(manager->lc); MSList *friends_from_db = NULL; char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); @@ -108,7 +109,7 @@ static void friends_migration(void) { linphone_core_set_friends_database_path(manager->lc, friends_db); friends = linphone_core_get_friend_list(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d"); - friends_from_db = linphone_core_fetch_friends_from_db(manager->lc); + friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, linphone_core_get_default_friend_list(manager->lc)); BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 3, int, "%d"); if (ms_list_size(friends_from_db) < 3) { goto end; @@ -117,25 +118,28 @@ static void friends_migration(void) { end: unlink(friends_db); ms_free(friends_db); - linphone_address_unref(addr); friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); linphone_core_manager_destroy(manager); } static void friends_sqlite_storage(void) { LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); LinphoneVCard *lvc = linphone_vcard_new(); LinphoneFriend *lf = linphone_friend_new(); LinphoneFriend *lf2 = NULL; LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); const MSList *friends = linphone_core_get_friend_list(manager->lc); MSList *friends_from_db = NULL; + MSList *friends_lists_from_db = NULL; char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); unlink(friends_db); linphone_core_set_friends_database_path(manager->lc, friends_db); - friends_from_db = linphone_core_fetch_friends_from_db(manager->lc); + friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, linphone_core_get_default_friend_list(manager->lc)); + BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); + friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); linphone_vcard_set_etag(lvc, "\"123-456789\""); @@ -143,14 +147,22 @@ static void friends_sqlite_storage(void) { linphone_friend_set_vcard(lf, lvc); linphone_friend_set_address(lf, addr); linphone_friend_set_name(lf, "Sylvain"); - linphone_core_add_friend(manager->lc, lf); + + linphone_core_add_friend_list(manager->lc, lfl); + + linphone_friend_list_set_display_name(lfl, "Test"); + linphone_friend_list_add_friend(lfl, lf); linphone_friend_unref(lf); + BC_ASSERT_EQUAL(lfl->storage_id, 1, int, "%d"); BC_ASSERT_EQUAL(lf->storage_id, 1, int, "%d"); friends = linphone_core_get_friend_list(manager->lc); - BC_ASSERT_EQUAL(ms_list_size(friends), 1, int, "%d"); + BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); - friends_from_db = linphone_core_fetch_friends_from_db(manager->lc); + friends_lists_from_db = linphone_core_fetch_friends_lists_from_db(manager->lc); + BC_ASSERT_EQUAL(ms_list_size(friends_lists_from_db), 1, int, "%d"); + + friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d"); if (ms_list_size(friends_from_db) < 1) { goto end; @@ -166,7 +178,7 @@ static void friends_sqlite_storage(void) { linphone_friend_set_name(lf, "Margaux"); linphone_friend_done(lf); friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); - friends_from_db = linphone_core_fetch_friends_from_db(manager->lc); + friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d"); if (ms_list_size(friends_from_db) < 1) { goto end; @@ -178,7 +190,7 @@ static void friends_sqlite_storage(void) { linphone_core_remove_friend(manager->lc, lf); friends = linphone_core_get_friend_list(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); - friends_from_db = linphone_core_fetch_friends_from_db(manager->lc); + friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 0, int, "%d"); end: @@ -206,14 +218,12 @@ static void carddav_sync_done(LinphoneCardDavContext *c, bool_t success, const c static void carddav_new_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_PTR_NOT_NULL_FATAL(lf); - linphone_friend_unref(lf); stats->new_contact_count++; } static void carddav_removed_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_PTR_NOT_NULL_FATAL(lf); - linphone_friend_unref(lf); stats->removed_contact_count++; } @@ -221,19 +231,17 @@ static void carddav_updated_contact(LinphoneCardDavContext *c, LinphoneFriend *n LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_PTR_NOT_NULL_FATAL(new_lf); BC_ASSERT_PTR_NOT_NULL_FATAL(old_lf); - linphone_friend_unref(new_lf); - linphone_friend_unref(old_lf); stats->updated_contact_count++; } static void carddav_sync(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); LinphoneCardDavContext *c = NULL; linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); - linphone_core_set_friend_list(manager->lc, lfl); + linphone_core_add_friend_list(manager->lc, lfl); c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); @@ -256,7 +264,7 @@ static void carddav_sync(void) { } static void carddav_sync_2(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); LinphoneFriend *lf = linphone_friend_new_with_address("\"Sylvain\" "); char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); @@ -264,13 +272,13 @@ static void carddav_sync_2(void) { LinphoneCardDavContext *c = NULL; linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); - linphone_core_set_friend_list(manager->lc, lfl); + linphone_core_add_friend_list(manager->lc, lfl); c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); unlink(friends_db); linphone_core_set_friends_database_path(manager->lc, friends_db); - linphone_core_add_friend(manager->lc, lf); + linphone_friend_list_add_friend(lfl, lf); linphone_friend_unref(lf); linphone_carddav_set_user_data(c, stats); @@ -297,7 +305,7 @@ static void carddav_sync_2(void) { } static void carddav_sync_3(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nFN:Sylvain Berfini\r\nIMPP;TYPE=work:sip:sylvain@sip.linphone.org\r\nEND:VCARD\r\n"); LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); @@ -306,13 +314,13 @@ static void carddav_sync_3(void) { LinphoneCardDavContext *c = NULL; linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); - linphone_core_set_friend_list(manager->lc, lfl); + linphone_core_add_friend_list(manager->lc, lfl); c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); unlink(friends_db); linphone_core_set_friends_database_path(manager->lc, friends_db); - linphone_core_add_friend(manager->lc, lf); + linphone_friend_list_add_friend(lfl, lf); linphone_friend_unref(lf); linphone_carddav_set_user_data(c, stats); @@ -337,7 +345,7 @@ static void carddav_sync_3(void) { } static void carddav_sync_4(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Margaux Clerc\r\nIMPP;TYPE=work:sip:margaux@sip.linphone.org\r\nEND:VCARD\r\n"); LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); @@ -345,7 +353,7 @@ static void carddav_sync_4(void) { LinphoneCardDavContext *c = NULL; linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); - linphone_core_set_friend_list(manager->lc, lfl); + linphone_core_add_friend_list(manager->lc, lfl); c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); @@ -377,17 +385,15 @@ static void carddav_sync_4(void) { static void carddav_contact_created(LinphoneFriendList *list, LinphoneFriend *lf) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); stats->new_contact_count++; - linphone_friend_unref(lf); } static void carddav_contact_deleted(LinphoneFriendList *list, LinphoneFriend *lf) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); stats->removed_contact_count++; - linphone_friend_unref(lf); } static void carddav_integration(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Margaux Clerc\r\nIMPP;TYPE=work:sip:margaux@sip.linphone.org\r\nEND:VCARD\r\n"); LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); @@ -399,7 +405,7 @@ static void carddav_integration(void) { linphone_friend_list_cbs_set_user_data(cbs, stats); linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); - linphone_core_set_friend_list(manager->lc, lfl); + linphone_core_add_friend_list(manager->lc, lfl); BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); BC_ASSERT_TRUE(linphone_vcard_generate_unique_id(lvc)); @@ -408,12 +414,18 @@ static void carddav_integration(void) { wait_for_until(manager->lc, NULL, NULL, 1, 2000); linphone_friend_list_remove_friend(lfl, lf); wait_for_until(manager->lc, NULL, NULL, 1, 2000); + linphone_friend_unref(lf); + + lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Ghislain Mary\r\nIMPP;TYPE=work:sip:ghislain@sip.linphone.org\r\nEND:VCARD\r\n"); + lf = linphone_friend_new_from_vcard(lvc); + _linphone_friend_list_add_friend(lfl, lf); BC_ASSERT_EQUAL(lfl->revision, 0, int, "%i"); - linphone_friend_list_synchronize_friends_from_server(lfl); wait_for_until(manager->lc, NULL, &stats->new_contact_count, 1, 2000); BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->removed_contact_count, 1, 2000); + BC_ASSERT_EQUAL(stats->removed_contact_count, 1, int, "%i"); BC_ASSERT_NOT_EQUAL(lfl->revision, 0, int, "%i"); ms_free(stats); From 03ca760d43d0fbe62b25f317ce2bbb9ceb36a421 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 14 Jan 2016 17:30:10 +0100 Subject: [PATCH 065/121] Added md5 check between edit and done on friends + fix all leaks related to friends or friendslists found by tester --- coreapi/carddav.c | 1 + coreapi/friend.c | 26 +++++++++++------------ coreapi/friendlist.c | 9 ++++++-- coreapi/linphonecore.c | 45 +++++++++++++++++++--------------------- coreapi/linphonefriend.h | 4 ++-- coreapi/vcard.cc | 32 ++++++++++++++++++++-------- coreapi/vcard.h | 6 +++--- coreapi/vcard_stubs.c | 4 ++-- tester/vcard_tester.c | 45 +++++++++++++++++++++++++--------------- 9 files changed, 100 insertions(+), 72 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 40dcca759..ceb782d4a 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -120,6 +120,7 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * cdc->contact_created_cb(cdc, lf); } } + linphone_friend_unref(lf); } vCards = ms_list_next(vCards); } diff --git a/coreapi/friend.c b/coreapi/friend.c index fe015a10b..bfb7d0457 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -535,19 +535,15 @@ void linphone_friend_edit(LinphoneFriend *fr) { } void linphone_friend_done(LinphoneFriend *fr) { - const char *previous_md5 = NULL; - ms_return_if_fail(fr); if (!fr->lc || !fr->friend_list) return; linphone_friend_apply(fr, fr->lc); linphone_friend_save(fr, fr->lc); if (fr && fr->vcard) { - previous_md5 = linphone_vcard_get_md5_hash(fr->vcard); - linphone_vcard_compute_md5_hash(fr->vcard); - if (previous_md5 && strcmp(previous_md5, linphone_vcard_get_md5_hash(fr->vcard)) != 0) { + if (linphone_vcard_compare_md5_hash(fr->vcard) != 0) { ms_debug("vCard's md5 has changed, mark friend as dirty"); - fr->friend_list->dirty_friends_to_update = ms_list_append(fr->friend_list->dirty_friends_to_update, fr); + fr->friend_list->dirty_friends_to_update = ms_list_append(fr->friend_list->dirty_friends_to_update, linphone_friend_ref(fr)); } } } @@ -561,7 +557,7 @@ LinphoneFriend * linphone_core_create_friend_with_address(LinphoneCore *lc, cons } void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) { - if ((lc->friends_lists == NULL) || (linphone_friend_list_add_friend(linphone_core_get_default_friend_list(lc), lf) != LinphoneFriendListOK)) return; + if (linphone_friend_list_add_friend(linphone_core_get_default_friend_list(lc), lf) != LinphoneFriendListOK) return; if (ms_list_find(lc->subscribers, lf)) { /*if this friend was in the pending subscriber list, now remove it from this list*/ lc->subscribers = ms_list_remove(lc->subscribers, lf); @@ -901,8 +897,6 @@ LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard) { fr->pol = LinphoneSPDeny; fr->subscribe = FALSE; - linphone_friend_set_vcard(fr, vcard); - if (sipAddresses) { const char *sipAddress = (const char *)sipAddresses->data; linphone_address = linphone_address_new(sipAddress); @@ -914,6 +908,7 @@ LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard) { if (name) { linphone_friend_set_name(fr, name); } + fr->vcard = vcard; return fr; } @@ -1053,10 +1048,15 @@ void linphone_core_friends_storage_init(LinphoneCore *lc) { lc->friends_db = db; friends_lists = linphone_core_fetch_friends_lists_from_db(lc); - while (friends_lists) { - LinphoneFriendList *list = (LinphoneFriendList *)friends_lists->data; - linphone_core_add_friend_list(lc, list); - friends_lists = ms_list_next(friends_lists); + if (friends_lists) { + lc->friends_lists = ms_list_free_with_data(lc->friends_lists, (void (*)(void*))linphone_friend_list_unref); + lc->friends_lists = NULL; + + while (friends_lists) { + LinphoneFriendList *list = (LinphoneFriendList *)friends_lists->data; + linphone_core_add_friend_list(lc, list); + friends_lists = ms_list_next(friends_lists); + } } } diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index 3ce918215..8ea3877cd 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -316,8 +316,12 @@ void _linphone_friend_list_release(LinphoneFriendList *list){ linphone_friend_list_cbs_unref(list->cbs); list->cbs = NULL; } - list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref); - list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release); + if (list->dirty_friends_to_update) { + list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref); + } + if (list->friends) { + list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release); + } linphone_friend_list_unref(list); } @@ -465,6 +469,7 @@ static void carddav_removed(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { LinphoneFriendList *lfl = cdc->friend_list; MSList *elem = ms_list_find(lfl->friends, lf); if (elem) { + linphone_friend_unref(lf); lfl->friends = ms_list_remove_link(lfl->friends, elem); } if (cdc->friend_list->cbs->contact_deleted_cb) { diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index d27384655..ccadf9465 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1687,8 +1687,6 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab const char *remote_provisioning_uri = NULL; LinphoneCoreVTable* local_vtable= linphone_core_v_table_new(); LinphoneCoreVTable *internal_vtable = linphone_core_v_table_new(); - LinphoneFriendList *list = NULL; - const char *rls_uri = NULL; ms_message("Initializing LinphoneCore %s", linphone_core_get_version()); @@ -1696,13 +1694,7 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab lc->data=userdata; lc->ringstream_autorelease=TRUE; - list = linphone_core_create_friend_list(lc); - rls_uri = lp_config_get_string(lc->config, "sip", "rls_uri", NULL); - if (rls_uri && lp_config_get_int(lc->config, "sip", "use_rls_presence", 0)) { - linphone_friend_list_set_rls_uri(list, rls_uri); - } - linphone_core_add_friend_list(lc, list); - linphone_friend_list_unref(list); + linphone_core_add_friend_list(lc, NULL); linphone_task_list_init(&lc->hooks); @@ -1941,9 +1933,12 @@ bool_t linphone_core_generic_confort_noise_enabled(const LinphoneCore *lc){ } const MSList* linphone_core_get_friend_list(const LinphoneCore *lc) { - if (lc->friends_lists && lc->friends_lists->data) { - LinphoneFriendList *list = (LinphoneFriendList *)lc->friends_lists->data; - return list->friends; + MSList *lists = lc->friends_lists; + if (lists) { + LinphoneFriendList *list = (LinphoneFriendList *)lists->data; + if (list) { + return list->friends; + } } return NULL; } @@ -1953,12 +1948,10 @@ const MSList* linphone_core_get_friends_lists(const LinphoneCore *lc) { } LinphoneFriendList* linphone_core_get_default_friend_list(const LinphoneCore *lc) { - LinphoneFriendList *list = NULL; - if (!lc->friends_lists) { - return NULL; + if (lc && lc->friends_lists) { + return (LinphoneFriendList *)lc->friends_lists->data; } - list = (LinphoneFriendList *)lc->friends_lists->data; - return list; + return NULL; } void linphone_core_remove_friend_list(LinphoneCore *lc, LinphoneFriendList *list) { @@ -1979,8 +1972,17 @@ void linphone_core_add_friend_list(LinphoneCore *lc, LinphoneFriendList *list) { } lc->friends_lists = ms_list_append(lc->friends_lists, linphone_friend_list_ref(list)); #ifdef FRIENDS_SQL_STORAGE_ENABLED - linphone_core_store_friends_list_in_db(lc, list); + linphone_core_store_friends_list_in_db(lc, list); #endif + } else { + const char *rls_uri = lp_config_get_string(lc->config, "sip", "rls_uri", NULL); + list = linphone_core_create_friend_list(lc); + linphone_friend_list_set_display_name(list, "_default"); + if (rls_uri && lp_config_get_int(lc->config, "sip", "use_rls_presence", 0)) { + linphone_friend_list_set_rls_uri(list, rls_uri); + } + lc->friends_lists = ms_list_append(lc->friends_lists, linphone_friend_list_ref(list)); + linphone_friend_list_unref(list); } } @@ -6391,13 +6393,8 @@ static void codecs_config_uninit(LinphoneCore *lc) void ui_config_uninit(LinphoneCore* lc) { - MSList *elem = NULL; ms_message("Destroying friends."); - for (elem = lc->friends_lists; elem != NULL; elem = ms_list_next(elem)) { - LinphoneFriendList *list = (LinphoneFriendList *)elem->data; - _linphone_friend_list_release(list); - } - lc->friends_lists = NULL; + lc->friends_lists = ms_list_free_with_data(lc->friends_lists, (void (*)(void*))_linphone_friend_list_release); if (lc->subscribers) { lc->subscribers = ms_list_free_with_data(lc->subscribers, (void (*)(void *))_linphone_friend_release); } diff --git a/coreapi/linphonefriend.h b/coreapi/linphonefriend.h index 7b11ec253..86c4a641a 100644 --- a/coreapi/linphonefriend.h +++ b/coreapi/linphonefriend.h @@ -357,9 +357,9 @@ LINPHONE_PUBLIC void linphone_core_interpret_friend_uri(LinphoneCore *lc, const LINPHONE_PUBLIC void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *fr); /** - * remove a friend from the buddy list + * Removes a friend from the buddy list * @param lc #LinphoneCore object - * @param fr #LinphoneFriend to add + * @param fr #LinphoneFriend to remove */ LINPHONE_PUBLIC void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend *fr); diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 77d136642..6b2c4fcd9 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -21,12 +21,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "belcard/belcard.hpp" #include "belcard/belcard_parser.hpp" #include "sal/sal.h" +#include struct _LinphoneVCard { shared_ptr belCard; char *etag; char *url; - char *md5; + unsigned char *md5; }; #ifdef __cplusplus @@ -225,20 +226,33 @@ const char* linphone_vcard_get_url(const LinphoneVCard *vCard) { } void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard) { + unsigned char digest[16]; + const char *text = NULL; if (!vCard) { return; } - if (vCard->md5) { - ms_free(vCard->md5); - } - //TODO: compute md5 hash + text = linphone_vcard_as_vcard4_string(vCard); + md5((unsigned char *)text, strlen(text), digest); + vCard->md5 = (unsigned char *)ms_malloc(sizeof(digest)); + memcpy(vCard->md5, digest, sizeof(digest)); } -const char *linphone_vcard_get_md5_hash(LinphoneVCard *vCard) { - if (!vCard) { - return NULL; +bool_t linphone_vcard_compare_md5_hash(LinphoneVCard *vCard) { + unsigned char *previous_md5 = vCard->md5; + unsigned char *new_md5 = NULL; + int result = -1; + + if (!previous_md5) { + return result; } - return vCard->md5; + + linphone_vcard_compute_md5_hash(vCard); + new_md5 = vCard->md5; + result = memcmp(new_md5, previous_md5, sizeof(previous_md5)); + + ms_free(previous_md5); + ms_free(new_md5); + return result; } #ifdef __cplusplus diff --git a/coreapi/vcard.h b/coreapi/vcard.h index 70f61b41c..e1d035fb3 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -176,11 +176,11 @@ const char* linphone_vcard_get_url(const LinphoneVCard *vCard); void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard); /** - * Computes the md5 hash for the vCard + * Compares the previously computed md5 hash (using linphone_vcard_compute_md5_hash) with the current one * @param[in] vCard the LinphoneVCard - * @return the last md5 hash computed for the vCard, or NULL if it wasn't computed yet + * @return 0 if the md5 hasn't changed, 1 otherwise */ -const char *linphone_vcard_get_md5_hash(LinphoneVCard *vCard); +bool_t linphone_vcard_compare_md5_hash(LinphoneVCard *vCard); /** * @} diff --git a/coreapi/vcard_stubs.c b/coreapi/vcard_stubs.c index 4f12c0415..500119f20 100644 --- a/coreapi/vcard_stubs.c +++ b/coreapi/vcard_stubs.c @@ -103,6 +103,6 @@ void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard) { } -const char *linphone_vcard_get_md5_hash(LinphoneVCard *vCard) { - return NULL; +bool_t linphone_vcard_compare_md5_hash(LinphoneVCard *vCard) { + return FALSE; } \ No newline at end of file diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 3a09bf890..029ed7fcc 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -126,7 +126,7 @@ static void friends_sqlite_storage(void) { LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); LinphoneVCard *lvc = linphone_vcard_new(); - LinphoneFriend *lf = linphone_friend_new(); + LinphoneFriend *lf = NULL; LinphoneFriend *lf2 = NULL; LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); const MSList *friends = linphone_core_get_friend_list(manager->lc); @@ -138,20 +138,18 @@ static void friends_sqlite_storage(void) { unlink(friends_db); linphone_core_set_friends_database_path(manager->lc, friends_db); friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, linphone_core_get_default_friend_list(manager->lc)); - BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); - friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); - BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); + BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 0, int, "%d"); linphone_vcard_set_etag(lvc, "\"123-456789\""); linphone_vcard_set_url(lvc, "http://dav.somewhere.fr/addressbook/me/someone.vcf"); - linphone_friend_set_vcard(lf, lvc); + lf = linphone_friend_new_from_vcard(lvc); linphone_friend_set_address(lf, addr); linphone_friend_set_name(lf, "Sylvain"); linphone_core_add_friend_list(manager->lc, lfl); - + linphone_friend_list_unref(lfl); linphone_friend_list_set_display_name(lfl, "Test"); - linphone_friend_list_add_friend(lfl, lf); + BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%i"); linphone_friend_unref(lf); BC_ASSERT_EQUAL(lfl->storage_id, 1, int, "%d"); BC_ASSERT_EQUAL(lf->storage_id, 1, int, "%d"); @@ -161,6 +159,7 @@ static void friends_sqlite_storage(void) { friends_lists_from_db = linphone_core_fetch_friends_lists_from_db(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends_lists_from_db), 1, int, "%d"); + friends_lists_from_db = ms_list_free_with_data(friends_lists_from_db, (void (*)(void *))linphone_friend_list_unref); friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d"); @@ -197,7 +196,6 @@ end: unlink(friends_db); ms_free(friends_db); linphone_address_unref(addr); - friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); linphone_core_manager_destroy(manager); } #endif @@ -242,6 +240,7 @@ static void carddav_sync(void) { linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_unref(lfl); c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); @@ -258,7 +257,6 @@ static void carddav_sync(void) { BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); ms_free(stats); - linphone_friend_list_unref(lfl); linphone_carddav_context_destroy(c); linphone_core_manager_destroy(manager); } @@ -273,12 +271,13 @@ static void carddav_sync_2(void) { linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_unref(lfl); c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); unlink(friends_db); linphone_core_set_friends_database_path(manager->lc, friends_db); - linphone_friend_list_add_friend(lfl, lf); + BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); linphone_friend_unref(lf); linphone_carddav_set_user_data(c, stats); @@ -299,7 +298,6 @@ static void carddav_sync_2(void) { ms_free(stats); unlink(friends_db); ms_free(friends_db); - linphone_friend_list_unref(lfl); linphone_carddav_context_destroy(c); linphone_core_manager_destroy(manager); } @@ -315,12 +313,13 @@ static void carddav_sync_3(void) { linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_unref(lfl); c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); unlink(friends_db); linphone_core_set_friends_database_path(manager->lc, friends_db); - linphone_friend_list_add_friend(lfl, lf); + BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); linphone_friend_unref(lf); linphone_carddav_set_user_data(c, stats); @@ -339,7 +338,6 @@ static void carddav_sync_3(void) { ms_free(stats); unlink(friends_db); ms_free(friends_db); - linphone_friend_list_unref(lfl); linphone_carddav_context_destroy(c); linphone_core_manager_destroy(manager); } @@ -354,6 +352,7 @@ static void carddav_sync_4(void) { linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_unref(lfl); c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); @@ -377,7 +376,6 @@ static void carddav_sync_4(void) { linphone_friend_unref(lf); ms_free(stats); - linphone_friend_list_unref(lfl); linphone_carddav_context_destroy(c); linphone_core_manager_destroy(manager); } @@ -410,15 +408,17 @@ static void carddav_integration(void) { BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); BC_ASSERT_TRUE(linphone_vcard_generate_unique_id(lvc)); BC_ASSERT_PTR_NOT_NULL(linphone_vcard_get_uid(lvc)); - linphone_friend_list_add_friend(lfl, lf); + BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); wait_for_until(manager->lc, NULL, NULL, 1, 2000); linphone_friend_list_remove_friend(lfl, lf); wait_for_until(manager->lc, NULL, NULL, 1, 2000); linphone_friend_unref(lf); + lf = NULL; lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Ghislain Mary\r\nIMPP;TYPE=work:sip:ghislain@sip.linphone.org\r\nEND:VCARD\r\n"); lf = linphone_friend_new_from_vcard(lvc); - _linphone_friend_list_add_friend(lfl, lf); + BC_ASSERT_EQUAL_FATAL(_linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); + linphone_friend_unref(lf); BC_ASSERT_EQUAL(lfl->revision, 0, int, "%i"); linphone_friend_list_synchronize_friends_from_server(lfl); @@ -428,8 +428,19 @@ static void carddav_integration(void) { BC_ASSERT_EQUAL(stats->removed_contact_count, 1, int, "%i"); BC_ASSERT_NOT_EQUAL(lfl->revision, 0, int, "%i"); + BC_ASSERT_EQUAL_FATAL(ms_list_size(lfl->friends), 1, int, "%i"); + lf = (LinphoneFriend *)lfl->friends->data; + linphone_friend_edit(lf); + linphone_friend_done(lf); + BC_ASSERT_EQUAL(ms_list_size(lf->friend_list->dirty_friends_to_update), 0, int, "%i"); + + linphone_core_set_network_reachable(manager->lc, FALSE); //To prevent the CardDAV update + linphone_friend_edit(lf); + linphone_friend_set_name(lf, "François Grisez"); + linphone_friend_done(lf); + BC_ASSERT_EQUAL(ms_list_size(lf->friend_list->dirty_friends_to_update), 1, int, "%i"); + ms_free(stats); - linphone_friend_unref(lf); linphone_friend_list_unref(lfl); linphone_core_manager_destroy(manager); } From 4a88bb639bb5a3ea6028cfb8398d96f3aa23316e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 15 Jan 2016 10:50:42 +0100 Subject: [PATCH 066/121] Fix presence tests --- coreapi/friend.c | 5 +---- coreapi/friendlist.c | 13 ++++++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index bfb7d0457..773cd6cb8 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -244,8 +244,7 @@ int linphone_friend_enable_subscribes(LinphoneFriend *fr, bool_t val){ return 0; } -int linphone_friend_set_inc_subscribe_policy(LinphoneFriend *fr, LinphoneSubscribePolicy pol) -{ +int linphone_friend_set_inc_subscribe_policy(LinphoneFriend *fr, LinphoneSubscribePolicy pol) { fr->pol=pol; return 0; } @@ -563,7 +562,6 @@ void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) { lc->subscribers = ms_list_remove(lc->subscribers, lf); linphone_friend_unref(lf); } - lf->lc = lc; /*I would prefer this to be done in linphone_friend_list_add_friend()*/ if (linphone_core_ready(lc)) linphone_friend_apply(lf, lc); else lf->commit = TRUE; linphone_friend_save(lf, lc); @@ -925,7 +923,6 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); if (lf) { if (LinphoneFriendListOK == linphone_friend_list_import_friend(linphone_core_get_default_friend_list(lc), lf)) { - lf->lc = lc; count++; } linphone_friend_unref(lf); diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index 8ea3877cd..ca650d9ae 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -280,8 +280,8 @@ static void linphone_friend_list_destroy(LinphoneFriendList *list) { if (list->event != NULL) linphone_event_unref(list->event); if (list->uri != NULL) ms_free(list->uri); if (list->cbs) linphone_friend_list_cbs_unref(list->cbs); - list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref); - list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release); + if (list->dirty_friends_to_update) list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref); + if (list->friends) list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release); } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriendList); @@ -403,11 +403,14 @@ LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *lis } LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf) { - if ((lf->lc != NULL) || (lf->uri == NULL)) return LinphoneFriendListInvalidFriend; - list->friends = ms_list_append(list->friends, linphone_friend_ref(lf)); - list->dirty_friends_to_update = ms_list_append(list->dirty_friends_to_update, linphone_friend_ref(lf)); + if (!lf->uri) { + ms_error("linphone_friend_list_import_friend(): invalid friend, no sip uri"); + return LinphoneFriendListInvalidFriend; + } lf->friend_list = list; lf->lc = list->lc; + list->friends = ms_list_append(list->friends, linphone_friend_ref(lf)); + list->dirty_friends_to_update = ms_list_append(list->dirty_friends_to_update, linphone_friend_ref(lf)); #ifdef FRIENDS_SQL_STORAGE_ENABLED linphone_core_store_friend_in_db(lf->lc, lf); #endif From 31b367c3fe7d35b4a6e3e8c78f26a3fb2e1801bc Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 15 Jan 2016 11:15:19 +0100 Subject: [PATCH 067/121] Fix fetch friends lists from db (they were empty) + added test for that --- coreapi/friend.c | 19 +++++++++++++++++-- tester/vcard_tester.c | 5 +++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index 773cd6cb8..e54df7408 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -1046,6 +1046,7 @@ void linphone_core_friends_storage_init(LinphoneCore *lc) { friends_lists = linphone_core_fetch_friends_lists_from_db(lc); if (friends_lists) { + ms_warning("Replacing current default friend list by the one(s) from the database"); lc->friends_lists = ms_list_free_with_data(lc->friends_lists, (void (*)(void*))linphone_friend_list_unref); lc->friends_lists = NULL; @@ -1281,6 +1282,7 @@ MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc, LinphoneFriendList char *buf; uint64_t begin,end; MSList *result = NULL; + MSList *elem = NULL; if (!lc || lc->friends_db == NULL || list == NULL) { ms_warning("Either lc (or list) is NULL or friends database wasn't initialized with linphone_core_friends_storage_init() yet"); @@ -1292,8 +1294,14 @@ MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc, LinphoneFriendList begin = ortp_get_cur_time_ms(); linphone_sql_request_friend(lc->friends_db, buf, &result); end = ortp_get_cur_time_ms(); - ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin)); + ms_message("%s(): %i results fetched, completed in %i ms",__FUNCTION__, ms_list_size(result), (int)(end-begin)); sqlite3_free(buf); + + for(elem = result; elem != NULL; elem = elem->next) { + LinphoneFriend *lf = (LinphoneFriend *)elem->data; + lf->lc = lc; + lf->friend_list = list; + } return result; } @@ -1302,6 +1310,7 @@ MSList* linphone_core_fetch_friends_lists_from_db(LinphoneCore *lc) { char *buf; uint64_t begin,end; MSList *result = NULL; + MSList *elem = NULL; if (!lc || lc->friends_db == NULL) { ms_warning("Either lc is NULL or friends database wasn't initialized with linphone_core_friends_storage_init() yet"); @@ -1313,8 +1322,14 @@ MSList* linphone_core_fetch_friends_lists_from_db(LinphoneCore *lc) { begin = ortp_get_cur_time_ms(); linphone_sql_request_friends_list(lc->friends_db, buf, &result); end = ortp_get_cur_time_ms(); - ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin)); + ms_message("%s(): %i results fetched, completed in %i ms",__FUNCTION__, ms_list_size(result), (int)(end-begin)); sqlite3_free(buf); + + for(elem = result; elem != NULL; elem = elem->next) { + LinphoneFriendList *lfl = (LinphoneFriendList *)elem->data; + lfl->lc = lc; + lfl->friends = linphone_core_fetch_friends_from_db(lc, lfl); + } return result; } diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 029ed7fcc..6cdf253db 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -159,6 +159,11 @@ static void friends_sqlite_storage(void) { friends_lists_from_db = linphone_core_fetch_friends_lists_from_db(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends_lists_from_db), 1, int, "%d"); + friends_from_db = ((LinphoneFriendList *)friends_lists_from_db->data)->friends; + BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d"); + lf2 = (LinphoneFriend *)friends_from_db->data; + BC_ASSERT_PTR_NOT_NULL(lf2->lc); + BC_ASSERT_PTR_NOT_NULL(lf2->friend_list); friends_lists_from_db = ms_list_free_with_data(friends_lists_from_db, (void (*)(void *))linphone_friend_list_unref); friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); From 39b2596744bb4e8f32b8f18dd3a17603c912a075 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 15 Jan 2016 11:40:00 +0100 Subject: [PATCH 068/121] Added carddav.c to CMakeLists.txt and Android.mk --- build/android/Android.mk | 1 + coreapi/CMakeLists.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/build/android/Android.mk b/build/android/Android.mk index 431cc942f..77f38ed34 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -45,6 +45,7 @@ LOCAL_SRC_FILES := \ callbacks.c \ call_log.c \ call_params.c \ + carddav.c \ chat.c \ chat_file_transfer.c \ conference.cc \ diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index 9d905c8b1..d38c25dfa 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -35,6 +35,7 @@ set(LINPHONE_HEADER_FILES buffer.h call_log.h call_params.h + carddav.h content.h event.h friendlist.h @@ -74,6 +75,7 @@ set(LINPHONE_SOURCE_FILES_C callbacks.c call_log.c call_params.c + carddav.c chat.c chat_file_transfer.c contactprovider.c From d31bd8dd77ec8b3668091614f89f74d7d86e4bb5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 15 Jan 2016 14:37:55 +0100 Subject: [PATCH 069/121] Few fixes --- coreapi/carddav.c | 3 ++- coreapi/friendlist.c | 4 +++- coreapi/linphonecore.c | 6 ++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index ceb782d4a..683b9dddd 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -617,7 +617,7 @@ void linphone_carddav_fetch_vcards(LinphoneCardDavContext *cdc) { static LinphoneCardDavQuery* linphone_carddav_create_addressbook_multiget_query(LinphoneCardDavContext *cdc, MSList *vcards) { LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); - char body[(ms_list_size(vcards)+1)*300]; + char *body = (char *)ms_malloc((ms_list_size(vcards) + 1) * 300 * sizeof(char)); MSList *iterator = vcards; query->context = cdc; @@ -639,6 +639,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_addressbook_multiget_query( } sprintf(body, "%s%s", body, ""); query->body = ms_strdup(body); + ms_free(body); return query; } diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index ca650d9ae..e022014fc 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -383,7 +383,9 @@ LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendList *li } LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf) { - if (lf->uri == NULL || lf->friend_list) { + if (!list || !lf->uri || lf->friend_list) { + if (!list) + ms_error("linphone_friend_list_add_friend(): invalid list, null"); if (!lf->uri) ms_error("linphone_friend_list_add_friend(): invalid friend, no sip uri"); if (lf->friend_list) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index ccadf9465..776506242 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -6494,6 +6494,12 @@ static void linphone_core_uninit(LinphoneCore *lc) if (lc->chat_db_file){ ms_free(lc->chat_db_file); } + if (lc->logs_db_file) { + ms_free(lc->logs_db_file); + } + if (lc->friends_db_file) { + ms_free(lc->friends_db_file); + } if (lc->ringtoneplayer) { linphone_ringtoneplayer_destroy(lc->ringtoneplayer); } From 9502d14f613077d14c7b2f8d6065ba45614bc760 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 15 Jan 2016 16:12:04 +0100 Subject: [PATCH 070/121] Fix call from gtk app to not public symbol --- gtk/friendlist.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/gtk/friendlist.c b/gtk/friendlist.c index 64fb615b4..1ace35f10 100644 --- a/gtk/friendlist.c +++ b/gtk/friendlist.c @@ -718,15 +718,8 @@ void linphone_gtk_show_friends(void){ void linphone_gtk_show_contact(LinphoneFriend *lf, GtkWidget *parent){ GtkWidget *w = linphone_gtk_create_window("contact", parent); char *uri; - const char *name; + const char *name = linphone_friend_get_name(lf); const LinphoneAddress *f_uri = linphone_friend_get_address(lf); - LinphoneVCard *vcard = linphone_friend_get_vcard(lf); - - if (vcard) { - name = linphone_vcard_get_full_name(vcard); - } else { - name = linphone_address_get_display_name(f_uri); - } uri=linphone_address_as_string_uri_only(f_uri); if (uri) { From 6ddff7e1fd1dd50e99fbc9b15c91bec556e87859 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 15 Jan 2016 16:44:03 +0100 Subject: [PATCH 071/121] Fix compil issue with cmake builder --- coreapi/vcard.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 6b2c4fcd9..7ab445242 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -225,8 +225,10 @@ const char* linphone_vcard_get_url(const LinphoneVCard *vCard) { return vCard->url; } +#define VCARD_MD5_HASH_SIZE 16 + void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard) { - unsigned char digest[16]; + unsigned char digest[VCARD_MD5_HASH_SIZE]; const char *text = NULL; if (!vCard) { return; @@ -248,7 +250,7 @@ bool_t linphone_vcard_compare_md5_hash(LinphoneVCard *vCard) { linphone_vcard_compute_md5_hash(vCard); new_md5 = vCard->md5; - result = memcmp(new_md5, previous_md5, sizeof(previous_md5)); + result = memcmp(new_md5, previous_md5, VCARD_MD5_HASH_SIZE); ms_free(previous_md5); ms_free(new_md5); From 63ec344f3b948e39cd04a2702c50268ca68bda85 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 18 Jan 2016 10:42:57 +0100 Subject: [PATCH 072/121] Updated CMakeLists to easy merge with master --- CMakeLists.txt | 3 +-- coreapi/CMakeLists.txt | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5316eb316..41c0bb8c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -238,10 +238,9 @@ endif() set(STRICT_OPTIONS_CPP ) set(STRICT_OPTIONS_C ) -set(STRICT_OPTIONS_CXX ) +set(STRICT_OPTIONS_CXX "-std=c++11") set(STRICT_OPTIONS_OBJC ) if(NOT MSVC) - list(APPEND STRICT_OPTIONS_CXX "-std=c++11") list(APPEND STRICT_OPTIONS_CPP "-Wall" "-Wuninitialized" "-Wno-error=deprecated-declarations") list(APPEND STRICT_OPTIONS_C "-Wdeclaration-after-statement" "-Wstrict-prototypes" "-Wno-error=strict-prototypes") if(CMAKE_C_COMPILER_ID STREQUAL "Clang") diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index d38c25dfa..08f9ce90d 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -146,10 +146,6 @@ add_definitions( -DLIBLINPHONE_EXPORTS ) -apply_compile_flags(LINPHONE_SOURCE_FILES_C "CPP" "C") -apply_compile_flags(LINPHONE_SOURCE_FILES_CXX "CPP" "CXX") -apply_compile_flags(LINPHONE_SOURCE_FILES_OBJC "CPP" "OBJC") - set(LIBS ${BELLESIP_LIBRARIES} ${MEDIASTREAMER2_LIBRARIES} @@ -186,6 +182,7 @@ endif() apply_compile_flags(LINPHONE_SOURCE_FILES_C "CPP" "C") apply_compile_flags(LINPHONE_SOURCE_FILES_CXX "CPP" "CXX") +apply_compile_flags(LINPHONE_SOURCE_FILES_OBJC "CPP" "OBJC") if(ENABLE_STATIC) add_library(linphone STATIC ${LINPHONE_HEADER_FILES} ${LINPHONE_SOURCE_FILES_C} ${LINPHONE_SOURCE_FILES_CXX} ${LINPHONE_SOURCE_FILES_OBJC}) From f001aaae9798bf2250e4a8aa5edf4102261d03c3 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 19 Jan 2016 14:07:41 +0100 Subject: [PATCH 073/121] This should fix broken JNI compilation --- coreapi/linphonecore_jni.cc | 12 ++++++++++-- java/common/org/linphone/core/LinphoneCore.java | 9 +++++++-- java/impl/org/linphone/core/LinphoneCoreImpl.java | 11 ++++++++--- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 93250f60d..c99033029 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1958,12 +1958,20 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_exportFriendsToVCardFile env->ReleaseStringUTFChars(jpath, path); } -extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setFriendList(JNIEnv* env +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_addFriendList(JNIEnv* env ,jobject thiz ,jlong lc ,jlong friendList ) { - linphone_core_set_friend_list((LinphoneCore*)lc,(LinphoneFriendList*)friendList); + linphone_core_add_friend_list((LinphoneCore*)lc,(LinphoneFriendList*)friendList); +} + +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_removeFriendList(JNIEnv* env + ,jobject thiz + ,jlong lc + ,jlong friendList + ) { + linphone_core_remove_friend_list((LinphoneCore*)lc,(LinphoneFriendList*)friendList); } extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getFriendList(JNIEnv* env diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index 85c97f6eb..2e92cbec6 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -1000,9 +1000,14 @@ public interface LinphoneCore { void addFriend(LinphoneFriend lf) throws LinphoneCoreException; /** - * Sets the friend list for the linphone core. + * Adds the friend list to the linphone core. */ - void setFriendList(LinphoneFriendList friendList) throws LinphoneCoreException; + void addFriendList(LinphoneFriendList friendList) throws LinphoneCoreException; + + /** + * Removes the friend list from the linphone core. + */ + void removeFriendList(LinphoneFriendList friendList) throws LinphoneCoreException; /** * Creates a friend list. diff --git a/java/impl/org/linphone/core/LinphoneCoreImpl.java b/java/impl/org/linphone/core/LinphoneCoreImpl.java index 221817bc3..014430adc 100644 --- a/java/impl/org/linphone/core/LinphoneCoreImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreImpl.java @@ -96,7 +96,8 @@ class LinphoneCoreImpl implements LinphoneCore { private native void setPreviewWindowId(long nativePtr, Object wid); private native void setDeviceRotation(long nativePtr, int rotation); private native void addFriend(long nativePtr,long friend); - private native void setFriendList(long nativePtr,long friendList); + private native void addFriendList(long nativePtr,long friendList); + private native void removeFriendList(long nativePtr,long friendList); private native LinphoneFriend[] getFriendList(long nativePtr); private native void setPresenceInfo(long nativePtr, int minutes_away, String alternative_contact, int status); private native int getPresenceInfo(long nativePtr); @@ -458,8 +459,12 @@ class LinphoneCoreImpl implements LinphoneCore { return new LinphoneFriendListImpl(this); } - public synchronized void setFriendList(LinphoneFriendList friendList) throws LinphoneCoreException { - setFriendList(nativePtr,((LinphoneFriendListImpl)friendList).nativePtr); + public synchronized void addFriendList(LinphoneFriendList friendList) throws LinphoneCoreException { + addFriendList(nativePtr,((LinphoneFriendListImpl)friendList).nativePtr); + } + + public synchronized void removeFriendList(LinphoneFriendList friendList) throws LinphoneCoreException { + removeFriendList(nativePtr,((LinphoneFriendListImpl)friendList).nativePtr); } public synchronized LinphoneFriend[] getFriendList() { From bfc7630ada1aa786e588163459ae5cec101382d3 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 21 Jan 2016 14:40:00 +0100 Subject: [PATCH 074/121] This should fix vcard tester --- CMakeLists.txt | 2 ++ coreapi/CMakeLists.txt | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41c0bb8c9..3aa9be035 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,6 +180,8 @@ if (ENABLE_VCARD) if(NOT BELCARD_FOUND) message(WARNING "Could not find the belcard library!") set(ENABLE_VCARD OFF CACHE BOOL "Enable vcard support." FORCE) + else() + add_definitions(-DVCARD_ENABLED) endif() endif() diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index 08f9ce90d..9cec28143 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -175,7 +175,6 @@ endif() if(BELCARD_FOUND) list(APPEND LIBS ${BELCARD_LIBRARIES}) list(APPEND LINPHONE_SOURCE_FILES_CXX vcard.cc) - add_definitions(-DVCARD_ENABLED) else() list(APPEND LINPHONE_SOURCE_FILES_C vcard_stubs.c) endif() From 49047285027eca22842cd116d92965d803c6571e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 25 Jan 2016 10:53:23 +0100 Subject: [PATCH 075/121] Fixed tester compil --- tester/presence_tester.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tester/presence_tester.c b/tester/presence_tester.c index af5e9729e..73e30ec51 100644 --- a/tester/presence_tester.c +++ b/tester/presence_tester.c @@ -759,7 +759,8 @@ static void test_presence_list_subscription_expire(void) { linphone_friend_list_set_rls_uri(lfl, rls_uri); lf = linphone_core_create_friend_with_address(laure->lc, "sip:michelle@sip.inexistentdomain.com"); linphone_friend_list_add_friend(lfl, lf); - linphone_core_set_friend_list(laure->lc, lfl); + linphone_core_remove_friend_list(laure->lc, linphone_core_get_default_friend_list(laure->lc)); + linphone_core_add_friend_list(laure->lc, lfl); linphone_friend_list_update_subscriptions(lfl,NULL,FALSE); linphone_friend_list_unref(lfl); From 43619c53a866bc36117eafb3cb2b69cb05dc72e5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 25 Jan 2016 12:58:05 +0100 Subject: [PATCH 076/121] Added contact updated callback in friendlist when using CardDAV --- coreapi/carddav.c | 35 +++++++++++++++++------------------ coreapi/friendlist.c | 41 +++++++++++++++++++++++++++++++---------- coreapi/friendlist.h | 20 ++++++++++++++++++++ coreapi/private.h | 1 + tester/vcard_tester.c | 21 +++++++++++++++++++-- 5 files changed, 88 insertions(+), 30 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 683b9dddd..78b70f695 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -110,6 +110,12 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * if (local_friend) { LinphoneFriend *lf2 = (LinphoneFriend *)local_friend->data; + lf->storage_id = lf2->storage_id; + lf->pol = lf2->pol; + lf->subscribe = lf2->subscribe; + lf->refkey = ms_strdup(lf2->refkey); + lf->presence_received = lf2->presence_received; + if (cdc->contact_updated_cb) { ms_debug("Contact updated: %s", linphone_friend_get_name(lf)); cdc->contact_updated_cb(cdc, lf, lf2); @@ -169,41 +175,33 @@ end: } static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend *lf) { - LinphoneVCard *lvc1 = linphone_vcard_new_from_vcard4_buffer(response->vcard); - LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf); - const char *uid1 = NULL, *uid2 = NULL; - if (!lvc1 || !lvc2) { - if (lvc1) linphone_vcard_free(lvc1); + if (!response->url || !lf || !lf->vcard || !linphone_vcard_get_url(lf->vcard)) { return 1; } - uid1 = linphone_vcard_get_uid(lvc1); - uid2 = linphone_vcard_get_uid(lvc2); - linphone_vcard_free(lvc1); - if (!uid1 || !uid2) { - return 1; - } - return strcmp(uid1, uid2); + return strcmp(response->url, linphone_vcard_get_url(lf->vcard)); } static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList *vCards) { if (vCards != NULL && ms_list_size(vCards) > 0) { MSList *friends = cdc->friend_list->friends; MSList *friends_to_remove = NULL; + MSList *temp_list = NULL; while (friends) { LinphoneFriend *lf = (LinphoneFriend *)friends->data; if (lf) { MSList *vCard = ms_list_find_custom(vCards, (int (*)(const void*, const void*))find_matching_vcard, lf); if (!vCard) { - ms_error("Local friend %s isn't in the remote vCard list, delete it", linphone_friend_get_name(lf)); - friends_to_remove = ms_list_append(friends_to_remove, lf); + ms_debug("Local friend %s isn't in the remote vCard list, delete it", linphone_friend_get_name(lf)); + temp_list = ms_list_append(temp_list, linphone_friend_ref(lf)); } else { LinphoneCardDavResponse *response = (LinphoneCardDavResponse *)vCard->data; ms_debug("Local friend %s is in the remote vCard list, check eTag", linphone_friend_get_name(lf)); if (response) { LinphoneVCard *lvc = linphone_friend_get_vcard(lf); - ms_debug("Local friend eTag is %s, remote vCard eTag is %s", linphone_vcard_get_etag(lvc), response->etag); - if (lvc && strcmp(linphone_vcard_get_etag(lvc), response->etag) == 0) { + const char *etag = linphone_vcard_get_etag(lvc); + ms_debug("Local friend eTag is %s, remote vCard eTag is %s", etag, response->etag); + if (lvc && etag && strcmp(etag, response->etag) == 0) { ms_list_remove(vCards, vCard); ms_free(response); } @@ -212,17 +210,18 @@ static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList } friends = ms_list_next(friends); } + friends_to_remove = temp_list; while(friends_to_remove) { LinphoneFriend *lf = (LinphoneFriend *)friends_to_remove->data; if (lf) { if (cdc->contact_removed_cb) { - ms_error("Contact removed: %s", linphone_friend_get_name(lf)); + ms_debug("Contact removed: %s", linphone_friend_get_name(lf)); cdc->contact_removed_cb(cdc, lf); } } friends_to_remove = ms_list_next(friends_to_remove); } - friends_to_remove = ms_list_free(friends_to_remove); + temp_list = ms_list_free_with_data(temp_list, (void (*)(void *))linphone_friend_unref); linphone_carddav_pull_vcards(cdc, vCards); } diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index e022014fc..fa8ba996b 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -72,6 +72,14 @@ void linphone_friend_list_cbs_set_contact_deleted(LinphoneFriendListCbs *cbs, Li cbs->contact_deleted_cb = cb; } +LinphoneFriendListContactUpdatedCb linphone_friend_list_cbs_get_contact_updated(const LinphoneFriendListCbs *cbs) { + return cbs->contact_updated_cb; +} + +void linphone_friend_list_cbs_set_contact_updated(LinphoneFriendListCbs *cbs, LinphoneFriendListContactUpdatedCb cb) { + cbs->contact_updated_cb = cb; +} + static char * create_resource_list_xml(const LinphoneFriendList *list) { char *xml_content = NULL; MSList *elem; @@ -423,6 +431,16 @@ static void carddav_done(LinphoneCardDavContext *cdc, bool_t success, const char linphone_carddav_context_destroy(cdc); } +LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFriendList *list, MSList *elem, LinphoneFriend *lf) { + if (!elem) { + return LinphoneFriendListNonExistentFriend; + } + lf->friend_list = NULL; + linphone_friend_unref(lf); + list->friends = ms_list_remove_link(list->friends, elem); + return LinphoneFriendListOK; +} + LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *lf) { MSList *elem = ms_list_find(list->friends, lf); LinphoneCardDavContext *cdc = linphone_carddav_context_new(list); @@ -436,10 +454,7 @@ LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList * linphone_carddav_delete_vcard(cdc, lf); } - lf->friend_list = NULL; - linphone_friend_unref(lf); - list->friends = ms_list_remove_link(list->friends, elem); - return LinphoneFriendListOK; + return _linphone_friend_list_remove_friend(list, elem, lf); } void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list) { @@ -472,11 +487,7 @@ static void carddav_created(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { static void carddav_removed(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { if (cdc) { LinphoneFriendList *lfl = cdc->friend_list; - MSList *elem = ms_list_find(lfl->friends, lf); - if (elem) { - linphone_friend_unref(lf); - lfl->friends = ms_list_remove_link(lfl->friends, elem); - } + linphone_friend_list_remove_friend(lfl, lf); if (cdc->friend_list->cbs->contact_deleted_cb) { cdc->friend_list->cbs->contact_deleted_cb(lfl, lf); } @@ -484,7 +495,17 @@ static void carddav_removed(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { } static void carddav_updated(LinphoneCardDavContext *cdc, LinphoneFriend *lf_new, LinphoneFriend *lf_old) { - //TODO + if (cdc) { + LinphoneFriendList *lfl = cdc->friend_list; + MSList *elem = ms_list_find(lfl->friends, lf_old); + if (elem) { + _linphone_friend_list_remove_friend(lfl, elem, lf_old); + } + _linphone_friend_list_add_friend(lfl, lf_new); + if (cdc->friend_list->cbs->contact_updated_cb) { + cdc->friend_list->cbs->contact_updated_cb(lfl, lf_new, lf_old); + } + } } void linphone_friend_list_synchronize_friends_from_server(LinphoneFriendList *list) { diff --git a/coreapi/friendlist.h b/coreapi/friendlist.h index 9f083eabe..c58c2930a 100644 --- a/coreapi/friendlist.h +++ b/coreapi/friendlist.h @@ -160,6 +160,7 @@ LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendList *li * @return LinphoneFriendListOK if removed successfully, LinphoneFriendListNonExistentFriend if the friend is not in the list. **/ LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *afriend); +LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFriendList *list, MSList *elem, LinphoneFriend *lf); /** * Find a friend in the friend list using a LinphoneAddress. @@ -232,6 +233,11 @@ typedef void (*LinphoneFriendListContactCreatedCb)(LinphoneFriendList *list, Lin **/ typedef void (*LinphoneFriendListContactDeletedCb)(LinphoneFriendList *list, LinphoneFriend *lf); +/** + * Callback used to notify a contact has been updated on the CardDAV server +**/ +typedef void (*LinphoneFriendListContactUpdatedCb)(LinphoneFriendList *list, LinphoneFriend *new_friend, LinphoneFriend *old_friend); + /** * Get the LinphoneFriendListCbs object associated with a LinphoneFriendList. * @param[in] request LinphoneXmlRpcRequest object @@ -294,6 +300,20 @@ LINPHONE_PUBLIC LinphoneFriendListContactDeletedCb linphone_friend_list_cbs_get_ **/ LINPHONE_PUBLIC void linphone_friend_list_cbs_set_contact_deleted(LinphoneFriendListCbs *cbs, LinphoneFriendListContactDeletedCb cb); +/** + * Get the contact updated callback. + * @param[in] cbs LinphoneFriendListCbs object. + * @return The current contact updated callback. +**/ +LINPHONE_PUBLIC LinphoneFriendListContactUpdatedCb linphone_friend_list_cbs_get_contact_updated(const LinphoneFriendListCbs *cbs); + +/** + * Set the contact updated callback. + * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] cb The contact updated to be used. +**/ +LINPHONE_PUBLIC void linphone_friend_list_cbs_set_contact_updated(LinphoneFriendListCbs *cbs, LinphoneFriendListContactUpdatedCb cb); + /** * * @param[in] list LinphoneFriendList object. diff --git a/coreapi/private.h b/coreapi/private.h index 1ed4fbd6c..ea871211d 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -700,6 +700,7 @@ struct _LinphoneFriendListCbs { void *user_data; LinphoneFriendListContactCreatedCb contact_created_cb; LinphoneFriendListContactDeletedCb contact_deleted_cb; + LinphoneFriendListContactUpdatedCb contact_updated_cb; }; BELLE_SIP_DECLARE_VPTR(LinphoneFriendListCbs); diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 6cdf253db..d678c3549 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -395,11 +395,18 @@ static void carddav_contact_deleted(LinphoneFriendList *list, LinphoneFriend *lf stats->removed_contact_count++; } +static void carddav_contact_updated(LinphoneFriendList *list, LinphoneFriend *new_friend, LinphoneFriend *old_friend) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); + stats->updated_contact_count++; +} + static void carddav_integration(void) { LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Margaux Clerc\r\nIMPP;TYPE=work:sip:margaux@sip.linphone.org\r\nEND:VCARD\r\n"); LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); + LinphoneVCard *lvc2 = NULL; + LinphoneFriend *lf2 = NULL; LinphoneFriendListCbs *cbs = NULL; LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); @@ -408,6 +415,7 @@ static void carddav_integration(void) { linphone_friend_list_cbs_set_user_data(cbs, stats); linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); + linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); linphone_core_add_friend_list(manager->lc, lfl); BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); @@ -425,12 +433,21 @@ static void carddav_integration(void) { BC_ASSERT_EQUAL_FATAL(_linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); linphone_friend_unref(lf); + lvc2 = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sylvain.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n"); + linphone_vcard_set_url(lvc2, "/sabredav/addressbookserver.php/addressbooks/sylvain/default/me.vcf"); + lf2 = linphone_friend_new_from_vcard(lvc2); + BC_ASSERT_EQUAL_FATAL(_linphone_friend_list_add_friend(lfl, lf2), LinphoneFriendListOK, int, "%d"); + linphone_friend_unref(lf2); + lf2 = NULL; + BC_ASSERT_EQUAL(lfl->revision, 0, int, "%i"); linphone_friend_list_synchronize_friends_from_server(lfl); - wait_for_until(manager->lc, NULL, &stats->new_contact_count, 1, 2000); - BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->new_contact_count, 0, 2000); + BC_ASSERT_EQUAL(stats->new_contact_count, 0, int, "%i"); wait_for_until(manager->lc, NULL, &stats->removed_contact_count, 1, 2000); BC_ASSERT_EQUAL(stats->removed_contact_count, 1, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->updated_contact_count, 1, 2000); + BC_ASSERT_EQUAL(stats->updated_contact_count, 1, int, "%i"); BC_ASSERT_NOT_EQUAL(lfl->revision, 0, int, "%i"); BC_ASSERT_EQUAL_FATAL(ms_list_size(lfl->friends), 1, int, "%i"); From 2ece607f18a09e6dcd347eafa18181748938e192 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 25 Jan 2016 14:14:53 +0100 Subject: [PATCH 077/121] Test that on contact update, previous friend fields are copied and new data is correct --- tester/vcard_tester.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index d678c3549..228f24f9a 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -409,6 +409,7 @@ static void carddav_integration(void) { LinphoneFriend *lf2 = NULL; LinphoneFriendListCbs *cbs = NULL; LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + const char *refkey = "toto"; linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); cbs = linphone_friend_list_get_callbacks(lfl); @@ -433,12 +434,12 @@ static void carddav_integration(void) { BC_ASSERT_EQUAL_FATAL(_linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); linphone_friend_unref(lf); - lvc2 = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sylvain.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n"); + lvc2 = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sberfini.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n"); linphone_vcard_set_url(lvc2, "/sabredav/addressbookserver.php/addressbooks/sylvain/default/me.vcf"); lf2 = linphone_friend_new_from_vcard(lvc2); + linphone_friend_set_ref_key(lf2, refkey); BC_ASSERT_EQUAL_FATAL(_linphone_friend_list_add_friend(lfl, lf2), LinphoneFriendListOK, int, "%d"); linphone_friend_unref(lf2); - lf2 = NULL; BC_ASSERT_EQUAL(lfl->revision, 0, int, "%i"); linphone_friend_list_synchronize_friends_from_server(lfl); @@ -452,6 +453,10 @@ static void carddav_integration(void) { BC_ASSERT_EQUAL_FATAL(ms_list_size(lfl->friends), 1, int, "%i"); lf = (LinphoneFriend *)lfl->friends->data; + BC_ASSERT_STRING_EQUAL(lf->refkey, refkey); + BC_ASSERT_EQUAL(lf->storage_id, lf2->storage_id, int, "%i"); + BC_ASSERT_STRING_EQUAL(linphone_address_as_string_uri_only(lf->uri), "sip:sylvain@sip.linphone.org"); + linphone_friend_edit(lf); linphone_friend_done(lf); BC_ASSERT_EQUAL(ms_list_size(lf->friend_list->dirty_friends_to_update), 0, int, "%i"); From 1f776d1f1cc3152cf53085663a5af8547bf4468e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 25 Jan 2016 14:48:11 +0100 Subject: [PATCH 078/121] Commit changes to friends list in db --- coreapi/friendlist.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index fa8ba996b..07386b314 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -356,6 +356,7 @@ void linphone_friend_list_set_display_name(LinphoneFriendList *list, const char } if (display_name != NULL) { list->display_name = ms_strdup(display_name); + linphone_core_store_friends_list_in_db(list->lc, list); } } @@ -370,6 +371,7 @@ void linphone_friend_list_set_rls_uri(LinphoneFriendList *list, const char *rls_ } if (rls_uri != NULL) { list->rls_uri = ms_strdup(rls_uri); + linphone_core_store_friends_list_in_db(list->lc, list); } } @@ -675,9 +677,11 @@ void linphone_friend_list_set_uri(LinphoneFriendList *list, const char *uri) { } if (uri != NULL) { list->uri = ms_strdup(uri); + linphone_core_store_friends_list_in_db(list->lc, list); } } void linphone_friend_list_update_revision(LinphoneFriendList *list, int rev) { list->revision = rev; + linphone_core_store_friends_list_in_db(list->lc, list); } \ No newline at end of file From 42d8d775b984ed7a2605ba884863fcc5cdef4a69 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 25 Jan 2016 17:44:27 +0100 Subject: [PATCH 079/121] Export a few symbols requiered for win32 tester + reworked a few APIs --- coreapi/friend.c | 3 ++- coreapi/friendlist.c | 55 +++++++++++++++---------------------------- coreapi/friendlist.h | 2 -- coreapi/private.h | 7 +++--- coreapi/vcard.h | 32 ++++++++++++------------- tester/vcard_tester.c | 4 ++-- 6 files changed, 42 insertions(+), 61 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index e54df7408..39a883371 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -837,6 +837,7 @@ void linphone_friend_set_vcard(LinphoneFriend *fr, LinphoneVCard *vcard) { linphone_vcard_free(fr->vcard); } fr->vcard = vcard; + linphone_friend_save(fr, fr->lc); } bool_t linphone_friend_create_vcard(LinphoneFriend *fr, const char *name) { @@ -922,7 +923,7 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * LinphoneVCard *vcard = (LinphoneVCard *)vcards->data; LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); if (lf) { - if (LinphoneFriendListOK == linphone_friend_list_import_friend(linphone_core_get_default_friend_list(lc), lf)) { + if (LinphoneFriendListOK == linphone_friend_list_import_friend(linphone_core_get_default_friend_list(lc), lf, TRUE)) { count++; } linphone_friend_unref(lf); diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index 07386b314..58f507a20 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -375,23 +375,6 @@ void linphone_friend_list_set_rls_uri(LinphoneFriendList *list, const char *rls_ } } -LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf) { - if (lf->uri == NULL || lf->friend_list) { - if (!lf->uri) - ms_error("linphone_friend_list_add_friend(): invalid friend, no sip uri"); - if (lf->friend_list) - ms_error("linphone_friend_list_add_friend(): invalid friend, already in list"); - return LinphoneFriendListInvalidFriend; - } - list->friends = ms_list_append(list->friends, linphone_friend_ref(lf)); - lf->friend_list = list; - lf->lc = list->lc; -#ifdef FRIENDS_SQL_STORAGE_ENABLED - linphone_core_store_friend_in_db(lf->lc, lf); -#endif - return LinphoneFriendListOK; -} - LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf) { if (!list || !lf->uri || lf->friend_list) { if (!list) @@ -409,20 +392,25 @@ LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *lis ms_warning("Friend %s already in list [%s], ignored.", tmp ? tmp : "unknown", list->display_name); if (tmp) ms_free(tmp); } else { - return linphone_friend_list_import_friend(list, lf); + return linphone_friend_list_import_friend(list, lf, TRUE); } return LinphoneFriendListOK; } -LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf) { - if (!lf->uri) { - ms_error("linphone_friend_list_import_friend(): invalid friend, no sip uri"); +LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf, bool_t synchronize) { + if (!lf->uri || lf->friend_list) { + if (!lf->uri) + ms_error("linphone_friend_list_add_friend(): invalid friend, no sip uri"); + if (lf->friend_list) + ms_error("linphone_friend_list_add_friend(): invalid friend, already in list"); return LinphoneFriendListInvalidFriend; } lf->friend_list = list; lf->lc = list->lc; list->friends = ms_list_append(list->friends, linphone_friend_ref(lf)); - list->dirty_friends_to_update = ms_list_append(list->dirty_friends_to_update, linphone_friend_ref(lf)); + if (synchronize) { + list->dirty_friends_to_update = ms_list_append(list->dirty_friends_to_update, linphone_friend_ref(lf)); + } #ifdef FRIENDS_SQL_STORAGE_ENABLED linphone_core_store_friend_in_db(lf->lc, lf); #endif @@ -433,16 +421,6 @@ static void carddav_done(LinphoneCardDavContext *cdc, bool_t success, const char linphone_carddav_context_destroy(cdc); } -LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFriendList *list, MSList *elem, LinphoneFriend *lf) { - if (!elem) { - return LinphoneFriendListNonExistentFriend; - } - lf->friend_list = NULL; - linphone_friend_unref(lf); - list->friends = ms_list_remove_link(list->friends, elem); - return LinphoneFriendListOK; -} - LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *lf) { MSList *elem = ms_list_find(list->friends, lf); LinphoneCardDavContext *cdc = linphone_carddav_context_new(list); @@ -456,7 +434,10 @@ LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList * linphone_carddav_delete_vcard(cdc, lf); } - return _linphone_friend_list_remove_friend(list, elem, lf); + lf->friend_list = NULL; + linphone_friend_unref(lf); + list->friends = ms_list_remove_link(list->friends, elem); + return LinphoneFriendListOK; } void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list) { @@ -479,7 +460,7 @@ void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list) { static void carddav_created(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { if (cdc) { LinphoneFriendList *lfl = cdc->friend_list; - _linphone_friend_list_add_friend(lfl, lf); + linphone_friend_list_import_friend(lfl, lf, FALSE); if (cdc->friend_list->cbs->contact_created_cb) { cdc->friend_list->cbs->contact_created_cb(lfl, lf); } @@ -501,9 +482,11 @@ static void carddav_updated(LinphoneCardDavContext *cdc, LinphoneFriend *lf_new, LinphoneFriendList *lfl = cdc->friend_list; MSList *elem = ms_list_find(lfl->friends, lf_old); if (elem) { - _linphone_friend_list_remove_friend(lfl, elem, lf_old); + lf_old->friend_list = NULL; + linphone_friend_unref(lf_old); + lfl->friends = ms_list_remove_link(lfl->friends, elem); } - _linphone_friend_list_add_friend(lfl, lf_new); + linphone_friend_list_import_friend(lfl, lf_new, FALSE); if (cdc->friend_list->cbs->contact_updated_cb) { cdc->friend_list->cbs->contact_updated_cb(lfl, lf_new, lf_old); } diff --git a/coreapi/friendlist.h b/coreapi/friendlist.h index c58c2930a..1bc643139 100644 --- a/coreapi/friendlist.h +++ b/coreapi/friendlist.h @@ -151,7 +151,6 @@ LINPHONE_PUBLIC void linphone_friend_list_set_rls_uri(LinphoneFriendList *list, * @return LinphoneFriendListOK if successfully added, LinphoneFriendListInvalidFriend if the friend is not valid. **/ LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *afriend); -LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *afriend); /** * Remove a friend from a friend list. @@ -160,7 +159,6 @@ LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendList *li * @return LinphoneFriendListOK if removed successfully, LinphoneFriendListNonExistentFriend if the friend is not in the list. **/ LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *afriend); -LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFriendList *list, MSList *elem, LinphoneFriend *lf); /** * Find a friend in the friend list using a LinphoneAddress. diff --git a/coreapi/private.h b/coreapi/private.h index ea871211d..880870430 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -425,10 +425,9 @@ void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf); void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf); void linphone_core_store_friends_list_in_db(LinphoneCore *lc, LinphoneFriendList *list); void linphone_core_remove_friends_list_from_db(LinphoneCore *lc, LinphoneFriendList *list); -MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc, LinphoneFriendList *list); -MSList* linphone_core_fetch_friends_lists_from_db(LinphoneCore *lc); -LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf); -LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf); +LINPHONE_PUBLIC MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc, LinphoneFriendList *list); +LINPHONE_PUBLIC MSList* linphone_core_fetch_friends_lists_from_db(LinphoneCore *lc); +LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf, bool_t synchronize); int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, socklen_t *socklen, int default_port); diff --git a/coreapi/vcard.h b/coreapi/vcard.h index e1d035fb3..53b4d5014 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -41,55 +41,55 @@ typedef struct _LinphoneVCard LinphoneVCard; /** * Creates a LinphoneVCard object that has a pointer to an empty vCard */ -LinphoneVCard* linphone_vcard_new(void); +LINPHONE_PUBLIC LinphoneVCard* linphone_vcard_new(void); /** * Deletes a LinphoneVCard object properly * @param[in] vCard the LinphoneVCard to destroy */ -void linphone_vcard_free(LinphoneVCard *vCard); +LINPHONE_PUBLIC void linphone_vcard_free(LinphoneVCard *vCard); /** * Uses belcard to parse the content of a file and returns all the vcards it contains as LinphoneVCards, or NULL if it contains none. * @param[in] file the path to the file to parse * @return \mslist{LinphoneVCard} */ -MSList* linphone_vcard_list_from_vcard4_file(const char *file); +LINPHONE_PUBLIC MSList* linphone_vcard_list_from_vcard4_file(const char *file); /** * Uses belcard to parse the content of a buffer and returns all the vcards it contains as LinphoneVCards, or NULL if it contains none. * @param[in] buffer the buffer to parse * @return \mslist{LinphoneVCard} */ -MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer); +LINPHONE_PUBLIC MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer); /** * Uses belcard to parse the content of a buffer and returns one vCard if possible, or NULL otherwise. * @param[in] buffer the buffer to parse * @return a LinphoneVCard if one could be parsed, or NULL otherwise */ -LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer); +LINPHONE_PUBLIC LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer); /** * Returns the vCard4 representation of the LinphoneVCard. * @param[in] vCard the LinphoneVCard * @return a const char * that represents the vCard */ -const char* linphone_vcard_as_vcard4_string(LinphoneVCard *vCard); +LINPHONE_PUBLIC const char* linphone_vcard_as_vcard4_string(LinphoneVCard *vCard); /** * Sets the FN attribute of the vCard (which is mandatory). * @param[in] vCard the LinphoneVCard * @param[in] name the display name to set for the vCard */ -void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name); +LINPHONE_PUBLIC void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name); /** * Returns the FN attribute of the vCard, or NULL if it isn't set yet. * @param[in] vCard the LinphoneVCard * @return the display name of the vCard, or NULL */ -const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard); +LINPHONE_PUBLIC const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard); /** * Adds a SIP address in the vCard, using the IMPP property @@ -117,7 +117,7 @@ void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const char *sip_ * @param[in] vCard the LinphoneVCard * @return \mslist{const char *} */ -MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard); +LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard); /** * Generates a random unique id for the vCard. @@ -125,49 +125,49 @@ MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard); * @param[in] vCard the LinphoneVCard * @return TRUE if operation is successful, otherwise FALSE (for example if it already has an unique ID) */ -bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard); +LINPHONE_PUBLIC bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard); /** * Sets the unique ID of the vCard * @param[in] vCard the LinphoneVCard * @param[in] uid the unique id */ -void linphone_vcard_set_uid(LinphoneVCard *vCard, const char *uid); +LINPHONE_PUBLIC void linphone_vcard_set_uid(LinphoneVCard *vCard, const char *uid); /** * Gets the UID of the vCard * @param[in] vCard the LinphoneVCard * @return the UID of the vCard, otherwise NULL */ -const char* linphone_vcard_get_uid(const LinphoneVCard *vCard); +LINPHONE_PUBLIC const char* linphone_vcard_get_uid(const LinphoneVCard *vCard); /** * Sets the eTAG of the vCard * @param[in] vCard the LinphoneVCard * @param[in] etag the eTAG */ -void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag); +LINPHONE_PUBLIC void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag); /** * Gets the eTag of the vCard * @param[in] vCard the LinphoneVCard * @return the eTag of the vCard in the CardDAV server, otherwise NULL */ -const char* linphone_vcard_get_etag(const LinphoneVCard *vCard); +LINPHONE_PUBLIC const char* linphone_vcard_get_etag(const LinphoneVCard *vCard); /** * Sets the URL of the vCard * @param[in] vCard the LinphoneVCard * @param[in] url the URL */ -void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url); +LINPHONE_PUBLIC void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url); /** * Gets the URL of the vCard * @param[in] vCard the LinphoneVCard * @return the URL of the vCard in the CardDAV server, otherwise NULL */ -const char* linphone_vcard_get_url(const LinphoneVCard *vCard); +LINPHONE_PUBLIC const char* linphone_vcard_get_url(const LinphoneVCard *vCard); /** * Computes the md5 hash for the vCard diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 228f24f9a..468b17f34 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -431,14 +431,14 @@ static void carddav_integration(void) { lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Ghislain Mary\r\nIMPP;TYPE=work:sip:ghislain@sip.linphone.org\r\nEND:VCARD\r\n"); lf = linphone_friend_new_from_vcard(lvc); - BC_ASSERT_EQUAL_FATAL(_linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); + BC_ASSERT_EQUAL_FATAL(linphone_friend_list_import_friend(lfl, lf, FALSE), LinphoneFriendListOK, int, "%d"); linphone_friend_unref(lf); lvc2 = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sberfini.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n"); linphone_vcard_set_url(lvc2, "/sabredav/addressbookserver.php/addressbooks/sylvain/default/me.vcf"); lf2 = linphone_friend_new_from_vcard(lvc2); linphone_friend_set_ref_key(lf2, refkey); - BC_ASSERT_EQUAL_FATAL(_linphone_friend_list_add_friend(lfl, lf2), LinphoneFriendListOK, int, "%d"); + BC_ASSERT_EQUAL_FATAL(linphone_friend_list_import_friend(lfl, lf2, FALSE), LinphoneFriendListOK, int, "%d"); linphone_friend_unref(lf2); BC_ASSERT_EQUAL(lfl->revision, 0, int, "%i"); From 6c146116b3f68637d222ae719be4c6a30733704e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 26 Jan 2016 15:30:58 +0100 Subject: [PATCH 080/121] Fixed a few leaks + added count test for thousand vcard import --- tester/vcard_tester.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 468b17f34..b52c5e156 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -34,6 +34,7 @@ static void linphone_vcard_import_export_friends_test(void) { char *export_filepath = create_filepath(bc_tester_get_writable_dir_prefix(), "export_vcards", "vcf"); const MSList *friends = linphone_core_get_friend_list(manager->lc); int count = 0; + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); BC_ASSERT_PTR_NOT_NULL_FATAL(linphone_core_get_default_friend_list(manager->lc)); @@ -48,13 +49,17 @@ static void linphone_vcard_import_export_friends_test(void) { friends = linphone_core_get_friend_list(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); - linphone_core_add_friend_list(manager->lc, linphone_core_create_friend_list(manager->lc)); + linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_unref(lfl); + lfl = NULL; count = linphone_core_import_friends_from_vcard4_file(manager->lc, export_filepath); BC_ASSERT_EQUAL(count, 3, int, "%d"); friends = linphone_core_get_friend_list(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d"); remove(export_filepath); + ms_free(import_filepath); + ms_free(export_filepath); linphone_core_manager_destroy(manager); } @@ -70,9 +75,13 @@ static void linphone_vcard_import_a_lot_of_friends_test(void) { end = clock(); friends = linphone_core_get_friend_list(manager->lc); + BC_ASSERT_EQUAL(ms_list_size(friends), 482, int, "%i"); // Thousand vcards contains 482 contacts with a SIP URI + elapsed = (double)(end - start); ms_error("Imported a thousand of vCards (only %i friends with SIP address found) in %f seconds", ms_list_size(friends), elapsed / CLOCKS_PER_SEC); BC_ASSERT_TRUE(elapsed < 1500000); // 1.5 seconds + + ms_free(import_filepath); linphone_core_manager_destroy(manager); } From 5c0bdf95bd1c4a16fdfdf93731e427c9fa05a847 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 26 Jan 2016 16:54:56 +0100 Subject: [PATCH 081/121] Fixed another leak --- coreapi/friend.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/coreapi/friend.c b/coreapi/friend.c index 39a883371..c5ab26db2 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -919,6 +919,10 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * #ifndef VCARD_ENABLED ms_error("vCard support wasn't enabled at compilation time"); #endif + if (!vcards) { + ms_error("Failed to parse the file %s", vcard_file); + return -1; + } while (vcards != NULL && vcards->data != NULL) { LinphoneVCard *vcard = (LinphoneVCard *)vcards->data; LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); @@ -927,6 +931,8 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * count++; } linphone_friend_unref(lf); + } else { + linphone_vcard_free(vcard); } vcards = ms_list_next(vcards); } From 5a7d0a07738aa0c66b753ce46beff45c635fedc7 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 27 Jan 2016 15:20:46 +0100 Subject: [PATCH 082/121] Attempt to fix __stack_chk_fail crash on MacOSX --- coreapi/carddav.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 78b70f695..b25969221 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -494,8 +494,17 @@ void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) if (!linphone_vcard_get_url(lvc)) { char *url = generate_url_from_server_address_and_uid(cdc->friend_list->uri); - linphone_vcard_set_url(lvc, url); - ms_free(url); + if (url) { + linphone_vcard_set_url(lvc, url); + ms_free(url); + } else { + const char *msg = "vCard doesn't have an URL, and friendlist doesn't have a CardDAV server set either, can't push it"; + ms_warning(msg); + if (cdc && cdc->sync_done_cb) { + cdc->sync_done_cb(cdc, FALSE, msg); + } + return; + } } query = linphone_carddav_create_put_query(cdc, lvc); @@ -505,8 +514,10 @@ void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) const char *msg = NULL; if (!lvc) { msg = "LinphoneVCard is NULL"; - } else if (!linphone_vcard_get_url(lvc)) { + } else if (!linphone_vcard_get_uid(lvc)) { msg = "LinphoneVCard doesn't have an UID"; + } else { + msg = "Unknown error"; } if (msg) { From 9cfd1404ef6d14c5578cd91e4e03dee40c2993ec Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 27 Jan 2016 15:46:55 +0100 Subject: [PATCH 083/121] Fixed dump mistake... --- coreapi/carddav.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index b25969221..4c3dbd958 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -499,7 +499,7 @@ void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) ms_free(url); } else { const char *msg = "vCard doesn't have an URL, and friendlist doesn't have a CardDAV server set either, can't push it"; - ms_warning(msg); + ms_warning("%s", msg); if (cdc && cdc->sync_done_cb) { cdc->sync_done_cb(cdc, FALSE, msg); } From 3c53c02fb7a6bf4147ce63615bc172071f999e68 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 28 Jan 2016 16:22:49 +0100 Subject: [PATCH 084/121] Fixed macosx stack_chk_fail, turns out can't use sal_generate_uuid with buffer of size 32... --- coreapi/carddav.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 4c3dbd958..69df31ff5 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -475,16 +475,19 @@ static LinphoneCardDavQuery* linphone_carddav_create_put_query(LinphoneCardDavCo } static char* generate_url_from_server_address_and_uid(const char *server_url) { + char *result = NULL; if (server_url) { - char uuid[32]; - if (sal_generate_uuid(uuid, sizeof(uuid)) == 0) { - char url[300]; - snprintf(url, sizeof(url), "%s/linphone-%s.vcf", server_url, uuid); + char *uuid = ms_malloc(64); + if (sal_generate_uuid(uuid, 64) == 0) { + char *url = ms_malloc(300); + snprintf(url, 300, "%s/linphone-%s.vcf", server_url, uuid); ms_debug("Generated url is %s", url); - return ms_strdup(url); + result = ms_strdup(url); + ms_free(url); } + ms_free(uuid); } - return NULL; + return result; } void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { @@ -549,8 +552,17 @@ void linphone_carddav_delete_vcard(LinphoneCardDavContext *cdc, LinphoneFriend * if (!linphone_vcard_get_url(lvc)) { char *url = generate_url_from_server_address_and_uid(cdc->friend_list->uri); - linphone_vcard_set_url(lvc, url); - ms_free(url); + if (url) { + linphone_vcard_set_url(lvc, url); + ms_free(url); + } else { + const char *msg = "vCard doesn't have an URL, and friendlist doesn't have a CardDAV server set either, can't delete it"; + ms_warning("%s", msg); + if (cdc && cdc->sync_done_cb) { + cdc->sync_done_cb(cdc, FALSE, msg); + } + return; + } } query = linphone_carddav_create_delete_query(cdc, lvc); From 4fba0f43045354cc0892a0b18760144d37fff1d6 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 28 Jan 2016 17:57:23 +0100 Subject: [PATCH 085/121] Disable time assert when importing a lot of vcards on Android (takes 20secs instead of 1.5, will have to check why) --- tester/vcard_tester.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index b52c5e156..b06d7e9f1 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -79,7 +79,9 @@ static void linphone_vcard_import_a_lot_of_friends_test(void) { elapsed = (double)(end - start); ms_error("Imported a thousand of vCards (only %i friends with SIP address found) in %f seconds", ms_list_size(friends), elapsed / CLOCKS_PER_SEC); +#ifndef ANDROID BC_ASSERT_TRUE(elapsed < 1500000); // 1.5 seconds +#endif ms_free(import_filepath); linphone_core_manager_destroy(manager); From 8725ed305d8c35bbe8002cf04254489b5b28c8d8 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 29 Jan 2016 11:18:39 +0100 Subject: [PATCH 086/121] Should fix the two vcard test not working yet on win32 --- .../liblinphone-tester/liblinphone-tester.csproj | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/build/windows10/liblinphone-tester/liblinphone-tester.csproj b/build/windows10/liblinphone-tester/liblinphone-tester.csproj index ab018cc05..7cf0be904 100644 --- a/build/windows10/liblinphone-tester/liblinphone-tester.csproj +++ b/build/windows10/liblinphone-tester/liblinphone-tester.csproj @@ -277,6 +277,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + @@ -309,7 +315,8 @@ XCopy /I /Y $(ProjectDir)..\..\..\tester\certificates\altname $(ProjectDir)Asset XCopy /I /Y $(ProjectDir)..\..\..\tester\certificates\cn $(ProjectDir)Assets\certificates\cn XCopy /I /Y $(ProjectDir)..\..\..\tester\images $(ProjectDir)Assets\images XCopy /I /Y $(ProjectDir)..\..\..\tester\rcfiles $(ProjectDir)Assets\rcfiles -XCopy /I /Y $(ProjectDir)..\..\..\tester\sounds $(ProjectDir)Assets\sounds +XCopy /I /Y $(ProjectDir)..\..\..\tester\sounds $(ProjectDir)Assets\sounds +XCopy /I /Y $(ProjectDir)..\..\..\tester\common $(ProjectDir)Assets\common - \ No newline at end of file + From 44ffb32dea0df2926d7170fa387086a0a233f530 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 29 Jan 2016 12:02:54 +0100 Subject: [PATCH 087/121] Fixed tester compilation --- tester/presence_tester.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tester/presence_tester.c b/tester/presence_tester.c index 8198367dd..13c603156 100644 --- a/tester/presence_tester.c +++ b/tester/presence_tester.c @@ -848,10 +848,11 @@ static void test_presence_list_subscribe_dialog_expire(void) { linphone_friend_list_add_friend(lfl, lf); lf = linphone_core_create_friend_with_address(laure->lc, "sip:michelle@sip.inexistentdomain.com"); linphone_friend_list_add_friend(lfl, lf); - linphone_core_set_friend_list(laure->lc, lfl); + linphone_core_remove_friend_list(laure->lc, linphone_core_get_default_friend_list(laure->lc)); + linphone_core_add_friend_list(laure->lc, lfl); linphone_friend_list_unref(lfl); linphone_core_set_presence_model(laure->lc, linphone_core_create_presence_model_with_activity(laure->lc, LinphonePresenceActivityOnline, NULL)); - linphone_friend_list_update_subscriptions(laure->lc->friendlist, NULL, FALSE); + linphone_friend_list_update_subscriptions(linphone_core_get_default_friend_list(laure->lc), NULL, FALSE); lcs = ms_list_append(lcs, laure->lc); lcs = ms_list_append(lcs, pauline->lc); @@ -861,12 +862,12 @@ static void test_presence_list_subscribe_dialog_expire(void) { enable_publish(pauline, TRUE); wait_for_list(lcs, &pauline->stat.number_of_NotifyPresenceReceived, 1, 2000); BC_ASSERT_GREATER(laure->stat.number_of_NotifyPresenceReceived, 1, int, "%d"); - BC_ASSERT_GREATER(laure->lc->friendlist->expected_notification_version, 1, int, "%d"); - lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity); + BC_ASSERT_GREATER(linphone_core_get_default_friend_list(laure->lc)->expected_notification_version, 1, int, "%d"); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusVacation, int, "%d"); BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d"); BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d"); - lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, "sip:michelle@sip.inexistentdomain.com"); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), "sip:michelle@sip.inexistentdomain.com"); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d"); BC_ASSERT_EQUAL(lf->presence_received, FALSE, int, "%d"); BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d"); @@ -886,7 +887,7 @@ static void test_presence_list_subscribe_dialog_expire(void) { linphone_core_set_presence_model(pauline->lc, linphone_core_create_presence_model_with_activity(pauline->lc, LinphonePresenceActivityAway, NULL)); BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_NotifyPresenceReceived, 3, 5000)); - lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity); + lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity); BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusAway, int, "%d"); linphone_core_manager_destroy(laure); From 5fe2c68b44bf3be237887bc0adcd8f19cc7671d5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 1 Feb 2016 15:41:22 +0100 Subject: [PATCH 088/121] Added method to import friends from buffer instead of file --- coreapi/friend.c | 30 +++++++++++++++++++ coreapi/linphonecore_jni.cc | 7 +++++ coreapi/linphonefriend.h | 8 +++++ .../org/linphone/core/LinphoneCore.java | 6 ++++ .../org/linphone/core/LinphoneCoreImpl.java | 6 ++++ 5 files changed, 57 insertions(+) diff --git a/coreapi/friend.c b/coreapi/friend.c index c5ab26db2..ca5a3a13b 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -942,6 +942,36 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * return count; } +int linphone_core_import_friends_from_vcard4_buffer(LinphoneCore *lc, const char *vcard_buffer) { + MSList *vcards = linphone_vcard_list_from_vcard4_buffer(vcard_buffer); + int count = 0; + +#ifndef VCARD_ENABLED + ms_error("vCard support wasn't enabled at compilation time"); +#endif + if (!vcards) { + ms_error("Failed to parse the buffer"); + return -1; + } + while (vcards != NULL && vcards->data != NULL) { + LinphoneVCard *vcard = (LinphoneVCard *)vcards->data; + LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); + if (lf) { + if (LinphoneFriendListOK == linphone_friend_list_import_friend(linphone_core_get_default_friend_list(lc), lf, TRUE)) { + count++; + } + linphone_friend_unref(lf); + } else { + linphone_vcard_free(vcard); + } + vcards = ms_list_next(vcards); + } +#ifndef FRIENDS_SQL_STORAGE_ENABLED + linphone_core_write_friends_config(lc); +#endif + return count; +} + void linphone_core_export_friends_as_vcard4_file(LinphoneCore *lc, const char *vcard_file) { FILE *file = NULL; const MSList *friends = linphone_core_get_friend_list(lc); diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index c73ed9ca0..6ce4611af 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1955,6 +1955,13 @@ extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_importFriendsFromVCardFi return count; } +extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_importFriendsFromVCardBuffer(JNIEnv* env, jobject thiz, jlong lc, jstring jbuffer) { + const char* buffer = env->GetStringUTFChars(jbuffer, NULL); + int count = linphone_core_import_friends_from_vcard4_buffer((LinphoneCore*)lc, buffer); + env->ReleaseStringUTFChars(jbuffer, buffer); + return count; +} + extern "C" void Java_org_linphone_core_LinphoneCoreImpl_exportFriendsToVCardFile(JNIEnv* env, jobject thiz, jlong lc, jstring jpath) { const char* path = env->GetStringUTFChars(jpath, NULL); linphone_core_export_friends_as_vcard4_file((LinphoneCore*)lc, path); diff --git a/coreapi/linphonefriend.h b/coreapi/linphonefriend.h index 86c4a641a..52afbae69 100644 --- a/coreapi/linphonefriend.h +++ b/coreapi/linphonefriend.h @@ -464,6 +464,14 @@ LINPHONE_PUBLIC LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vc */ LINPHONE_PUBLIC int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char *vcard_file); +/** + * Creates and adds LinphoneFriend objects to LinphoneCore from a buffer that contains the vCard(s) to parse + * @param[in] lc the LinphoneCore object + * @param[in] vcard_buffer the buffer that contains the vCard(s) to parse + * @return the amount of linphone friends created + */ +LINPHONE_PUBLIC int linphone_core_import_friends_from_vcard4_buffer(LinphoneCore *lc, const char *vcard_buffer); + /** * Creates and export LinphoneFriend objects from LinphoneCore to a file using vCard 4 format * @param[in] lc the LinphoneCore object diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index 389d59f87..6afcb11b9 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -2270,6 +2270,12 @@ public interface LinphoneCore { **/ public int importFriendsFromVCardFile(String file); + /** + * Imports LinphoneFriends from a vCard 4 buffer + * @return the number of friend imported + **/ + public int importFriendsFromVCardBuffer(String buffer); + /** * Exports LinphoneFriends to a vCard 4 file **/ diff --git a/java/impl/org/linphone/core/LinphoneCoreImpl.java b/java/impl/org/linphone/core/LinphoneCoreImpl.java index 54a904c79..feb0716a6 100644 --- a/java/impl/org/linphone/core/LinphoneCoreImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreImpl.java @@ -1627,6 +1627,12 @@ class LinphoneCoreImpl implements LinphoneCore { return importFriendsFromVCardFile(nativePtr, file); } + private native int importFriendsFromVCardBuffer(long nativePtr, String buffer); + @Override + public int importFriendsFromVCardBuffer(String buffer) { + return importFriendsFromVCardBuffer(nativePtr, buffer); + } + private native void exportFriendsToVCardFile(long nativePtr, String file); @Override public void exportFriendsToVCardFile(String file) { From 06f9d69a78f62ae3f3a4fb7294962844ee7b3cfc Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 1 Feb 2016 15:42:02 +0100 Subject: [PATCH 089/121] Added vtable callbacks for friend list created / removed + tests --- coreapi/friend.c | 2 ++ coreapi/linphonecore.c | 8 +++--- coreapi/linphonecore.h | 16 +++++++++++ coreapi/private.h | 2 ++ coreapi/vtables.c | 10 +++++++ tester/vcard_tester.c | 60 +++++++++++++++++++++++++++++++----------- 6 files changed, 80 insertions(+), 18 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index ca5a3a13b..4f245f6a7 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -918,6 +918,7 @@ int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char * #ifndef VCARD_ENABLED ms_error("vCard support wasn't enabled at compilation time"); + return -1; #endif if (!vcards) { ms_error("Failed to parse the file %s", vcard_file); @@ -948,6 +949,7 @@ int linphone_core_import_friends_from_vcard4_buffer(LinphoneCore *lc, const char #ifndef VCARD_ENABLED ms_error("vCard support wasn't enabled at compilation time"); + return -1; #endif if (!vcards) { ms_error("Failed to parse the buffer"); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 54303df26..93791eafe 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1937,12 +1937,13 @@ LinphoneFriendList* linphone_core_get_default_friend_list(const LinphoneCore *lc void linphone_core_remove_friend_list(LinphoneCore *lc, LinphoneFriendList *list) { MSList *elem = ms_list_find(lc->friends_lists, list); if (elem == NULL) return; - list->lc = NULL; - linphone_friend_list_unref(list); - lc->friends_lists = ms_list_remove_link(lc->friends_lists, elem); #ifdef FRIENDS_SQL_STORAGE_ENABLED linphone_core_remove_friends_list_from_db(lc, list); #endif + linphone_core_notify_friend_list_removed(lc, list); + list->lc = NULL; + linphone_friend_list_unref(list); + lc->friends_lists = ms_list_remove_link(lc->friends_lists, elem); } void linphone_core_add_friend_list(LinphoneCore *lc, LinphoneFriendList *list) { @@ -1954,6 +1955,7 @@ void linphone_core_add_friend_list(LinphoneCore *lc, LinphoneFriendList *list) { #ifdef FRIENDS_SQL_STORAGE_ENABLED linphone_core_store_friends_list_in_db(lc, list); #endif + linphone_core_notify_friend_list_created(lc, list); } else { const char *rls_uri = lp_config_get_string(lc->config, "sip", "rls_uri", NULL); list = linphone_core_create_friend_list(lc); diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index a68ba9556..a0f069657 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -2068,6 +2068,20 @@ typedef void (*LinphoneCoreLogCollectionUploadStateChangedCb)(LinphoneCore *lc, */ typedef void (*LinphoneCoreLogCollectionUploadProgressIndicationCb)(LinphoneCore *lc, size_t offset, size_t total); +/** + * Callback prototype for reporting when a friend list has been added to the core friends list. + * @param[in] lc LinphoneCore object + * @param[in] list LinphoneFriendList object + */ +typedef void (*LinphoneCoreFriendListCreatedCb) (LinphoneCore *lc, LinphoneFriendList *list); + +/** + * Callback prototype for reporting when a friend list has been removed from the core friends list. + * @param[in] lc LinphoneCore object + * @param[in] list LinphoneFriendList object + */ +typedef void (*LinphoneCoreFriendListRemovedCb) (LinphoneCore *lc, LinphoneFriendList *list); + /** * This structure holds all callbacks that the application should implement. * None is mandatory. @@ -2105,6 +2119,8 @@ typedef struct _LinphoneCoreVTable{ LinphoneCoreNetworkReachableCb network_reachable; /**< Callback to report IP network status (I.E up/down )*/ LinphoneCoreLogCollectionUploadStateChangedCb log_collection_upload_state_changed; /**< Callback to upload collected logs */ LinphoneCoreLogCollectionUploadProgressIndicationCb log_collection_upload_progress_indication; /**< Callback to indicate log collection upload progress */ + LinphoneCoreFriendListCreatedCb friend_list_created; + LinphoneCoreFriendListRemovedCb friend_list_removed; void *user_data; /**valid=1; diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index b06d7e9f1..7fb0272a4 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -133,22 +133,46 @@ end: linphone_core_manager_destroy(manager); } +typedef struct _LinphoneFriendListStats { + int new_list_count; + int removed_list_count; +} LinphoneFriendListStats; + +static void friend_list_created_cb(LinphoneCore *lc, LinphoneFriendList *list) { + LinphoneFriendListStats *stats = (LinphoneFriendListStats *)linphone_friend_list_get_user_data(list); + stats->new_list_count++; +} + +static void friend_list_removed_cb(LinphoneCore *lc, LinphoneFriendList *list) { + LinphoneFriendListStats *stats = (LinphoneFriendListStats *)linphone_friend_list_get_user_data(list); + stats->removed_list_count++; +} + static void friends_sqlite_storage(void) { - LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); - LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); - LinphoneVCard *lvc = linphone_vcard_new(); + LinphoneCoreVTable *v_table = linphone_core_v_table_new(); + LinphoneCore* lc = NULL; + LinphoneFriendList *lfl = NULL; LinphoneFriend *lf = NULL; LinphoneFriend *lf2 = NULL; + LinphoneVCard *lvc = linphone_vcard_new(); LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); - const MSList *friends = linphone_core_get_friend_list(manager->lc); + const MSList *friends = NULL; MSList *friends_from_db = NULL; MSList *friends_lists_from_db = NULL; char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); + LinphoneFriendListStats *stats = (LinphoneFriendListStats *)ms_new0(LinphoneFriendListStats, 1); + + v_table->friend_list_created = friend_list_created_cb; + v_table->friend_list_removed = friend_list_removed_cb; + lc = linphone_core_new(v_table, NULL, NULL, NULL); + friends = linphone_core_get_friend_list(lc); + lfl = linphone_core_create_friend_list(lc); + linphone_friend_list_set_user_data(lfl, stats); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); unlink(friends_db); - linphone_core_set_friends_database_path(manager->lc, friends_db); - friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, linphone_core_get_default_friend_list(manager->lc)); + linphone_core_set_friends_database_path(lc, friends_db); + friends_from_db = linphone_core_fetch_friends_from_db(lc, linphone_core_get_default_friend_list(lc)); BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 0, int, "%d"); linphone_vcard_set_etag(lvc, "\"123-456789\""); @@ -157,7 +181,9 @@ static void friends_sqlite_storage(void) { linphone_friend_set_address(lf, addr); linphone_friend_set_name(lf, "Sylvain"); - linphone_core_add_friend_list(manager->lc, lfl); + linphone_core_add_friend_list(lc, lfl); + wait_for_until(lc, NULL, &stats->new_list_count, 1, 1000); + BC_ASSERT_EQUAL(stats->new_list_count, 1, int, "%i"); linphone_friend_list_unref(lfl); linphone_friend_list_set_display_name(lfl, "Test"); BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%i"); @@ -165,10 +191,10 @@ static void friends_sqlite_storage(void) { BC_ASSERT_EQUAL(lfl->storage_id, 1, int, "%d"); BC_ASSERT_EQUAL(lf->storage_id, 1, int, "%d"); - friends = linphone_core_get_friend_list(manager->lc); + friends = linphone_core_get_friend_list(lc); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); - friends_lists_from_db = linphone_core_fetch_friends_lists_from_db(manager->lc); + friends_lists_from_db = linphone_core_fetch_friends_lists_from_db(lc); BC_ASSERT_EQUAL(ms_list_size(friends_lists_from_db), 1, int, "%d"); friends_from_db = ((LinphoneFriendList *)friends_lists_from_db->data)->friends; BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d"); @@ -177,7 +203,7 @@ static void friends_sqlite_storage(void) { BC_ASSERT_PTR_NOT_NULL(lf2->friend_list); friends_lists_from_db = ms_list_free_with_data(friends_lists_from_db, (void (*)(void *))linphone_friend_list_unref); - friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); + friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl); BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d"); if (ms_list_size(friends_from_db) < 1) { goto end; @@ -193,7 +219,7 @@ static void friends_sqlite_storage(void) { linphone_friend_set_name(lf, "Margaux"); linphone_friend_done(lf); friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); - friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); + friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl); BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d"); if (ms_list_size(friends_from_db) < 1) { goto end; @@ -202,17 +228,21 @@ static void friends_sqlite_storage(void) { BC_ASSERT_STRING_EQUAL(linphone_friend_get_name(lf2), "Margaux"); friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); - linphone_core_remove_friend(manager->lc, lf); - friends = linphone_core_get_friend_list(manager->lc); + linphone_core_remove_friend(lc, lf); + friends = linphone_core_get_friend_list(lc); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); - friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); + friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl); BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 0, int, "%d"); + + linphone_core_remove_friend_list(lc, lfl); + wait_for_until(lc, NULL, &stats->removed_list_count, 1, 1000); + BC_ASSERT_EQUAL(stats->removed_list_count, 1, int, "%i"); end: unlink(friends_db); ms_free(friends_db); linphone_address_unref(addr); - linphone_core_manager_destroy(manager); + linphone_core_destroy(lc); } #endif From 1d754ddff4ceaf2a32de5e606e33944c430a2bf6 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 1 Feb 2016 16:04:58 +0100 Subject: [PATCH 090/121] Automatically generate UID on PUT if not yet created + improved some tests --- coreapi/carddav.c | 7 ++++--- coreapi/vcard.h | 4 ++-- tester/vcard_tester.c | 14 +++++++------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 69df31ff5..964f3f6e6 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -492,8 +492,11 @@ static char* generate_url_from_server_address_and_uid(const char *server_url) { void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { LinphoneVCard *lvc = linphone_friend_get_vcard(lf); - if (lvc && linphone_vcard_get_uid(lvc)) { + if (lvc) { LinphoneCardDavQuery *query = NULL; + if (!linphone_vcard_get_uid(lvc)) { + linphone_vcard_generate_unique_id(lvc); + } if (!linphone_vcard_get_url(lvc)) { char *url = generate_url_from_server_address_and_uid(cdc->friend_list->uri); @@ -517,8 +520,6 @@ void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) const char *msg = NULL; if (!lvc) { msg = "LinphoneVCard is NULL"; - } else if (!linphone_vcard_get_uid(lvc)) { - msg = "LinphoneVCard doesn't have an UID"; } else { msg = "Unknown error"; } diff --git a/coreapi/vcard.h b/coreapi/vcard.h index 53b4d5014..ad1901cae 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -125,14 +125,14 @@ LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vC * @param[in] vCard the LinphoneVCard * @return TRUE if operation is successful, otherwise FALSE (for example if it already has an unique ID) */ -LINPHONE_PUBLIC bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard); +bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard); /** * Sets the unique ID of the vCard * @param[in] vCard the LinphoneVCard * @param[in] uid the unique id */ -LINPHONE_PUBLIC void linphone_vcard_set_uid(LinphoneVCard *vCard, const char *uid); +void linphone_vcard_set_uid(LinphoneVCard *vCard, const char *uid); /** * Gets the UID of the vCard diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 7fb0272a4..931e318b7 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -408,11 +408,9 @@ static void carddav_sync_4(void) { linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact); linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact); - BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); - BC_ASSERT_TRUE(linphone_vcard_generate_unique_id(lvc)); - BC_ASSERT_PTR_NOT_NULL(linphone_vcard_get_uid(lvc)); - + BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); linphone_carddav_put_vcard(c, lf); + BC_ASSERT_PTR_NOT_NULL(linphone_vcard_get_uid(lvc)); wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); @@ -461,12 +459,14 @@ static void carddav_integration(void) { linphone_core_add_friend_list(manager->lc, lfl); BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); - BC_ASSERT_TRUE(linphone_vcard_generate_unique_id(lvc)); - BC_ASSERT_PTR_NOT_NULL(linphone_vcard_get_uid(lvc)); + BC_ASSERT_EQUAL(ms_list_size(lfl->dirty_friends_to_update), 0, int, "%d"); BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); + BC_ASSERT_EQUAL(ms_list_size(lfl->dirty_friends_to_update), 1, int, "%d"); wait_for_until(manager->lc, NULL, NULL, 1, 2000); + BC_ASSERT_EQUAL(ms_list_size(lfl->dirty_friends_to_update), 0, int, "%d"); + BC_ASSERT_PTR_NOT_NULL(linphone_vcard_get_uid(lvc)); linphone_friend_list_remove_friend(lfl, lf); - wait_for_until(manager->lc, NULL, NULL, 1, 2000); + BC_ASSERT_EQUAL(ms_list_size(lfl->friends), 0, int, "%d"); linphone_friend_unref(lf); lf = NULL; From 6a2a62008f5d8331d614a7601d42b70085ffd876 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 1 Feb 2016 16:24:27 +0100 Subject: [PATCH 091/121] Added JNI bindings for newly created vtable callbacks --- coreapi/linphonecore_jni.cc | 77 +++++++++++++++++++ .../linphone/core/LinphoneCoreListener.java | 14 ++++ .../core/LinphoneCoreListenerBase.java | 11 +++ 3 files changed, 102 insertions(+) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 6ce4611af..02cd5325d 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -294,6 +294,11 @@ public: friendClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneFriendImpl"));; friendCtrId = env->GetMethodID(friendClass,"", "(J)V"); + + friendListClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneFriendListImpl"));; + friendListCtrId = env->GetMethodID(friendListClass,"", "(J)V"); + friendListCreatedId = env->GetMethodID(listenerClass, "friendListCreated", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriendList;)V"); + friendListRemovedId = env->GetMethodID(listenerClass, "friendListRemoved", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriendList;)V"); addressClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneAddressImpl")); addressCtrId = env->GetMethodID(addressClass,"", "(J)V"); @@ -333,6 +338,7 @@ public: env->DeleteGlobalRef(chatMessageClass); env->DeleteGlobalRef(chatRoomClass); env->DeleteGlobalRef(friendClass); + env->DeleteGlobalRef(friendListClass); env->DeleteGlobalRef(infoMessageClass); env->DeleteGlobalRef(linphoneEventClass); env->DeleteGlobalRef(subscriptionStateClass); @@ -402,6 +408,11 @@ public: jclass friendClass; jmethodID friendCtrId; + jclass friendListClass; + jmethodID friendListCtrId; + jmethodID friendListCreatedId; + jmethodID friendListRemovedId; + jclass addressClass; jmethodID addressCtrId; @@ -526,6 +537,31 @@ jobject getFriend(JNIEnv *env, LinphoneFriend *lfriend){ return jobj; } +jobject getFriendList(JNIEnv *env, LinphoneFriendList *lfriendList){ + jobject jobj=0; + + if (lfriendList != NULL){ + LinphoneCore *lc = linphone_friend_list_get_core(lfriendList); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + + void *up=linphone_friend_list_get_user_data(lfriendList); + + if (up == NULL){ + jobj=env->NewObject(ljb->friendListClass, ljb->friendListCtrId, (jlong)lfriendList); + linphone_friend_list_set_user_data(lfriendList,(void*)env->NewWeakGlobalRef(jobj)); + linphone_friend_list_ref(lfriendList); + }else{ + + jobj=env->NewLocalRef((jobject)up); + if (jobj == NULL){ + jobj=env->NewObject(ljb->friendListClass, ljb->friendListCtrId, (jlong)lfriendList); + linphone_friend_list_set_user_data(lfriendList,(void*)env->NewWeakGlobalRef(jobj)); + } + } + } + return jobj; +} + jobject getEvent(JNIEnv *env, LinphoneEvent *lev){ if (lev==NULL) return NULL; jobject jev=(jobject)linphone_event_get_user_data(lev); @@ -638,6 +674,13 @@ public: if (ljb->logCollectionUploadStateId) { vTable->log_collection_upload_state_changed = logCollectionUploadStateChange; } + + if (ljb->friendListCreatedId) { + vTable->friend_list_created = friendListCreated; + } + if (ljb->friendListRemovedId) { + vTable->friend_list_removed = friendListRemoved; + } } ~LinphoneCoreData() { @@ -1208,6 +1251,40 @@ public: env->DeleteLocalRef(msg); } } + static void friendListCreated(LinphoneCore *lc, LinphoneFriendList *list) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + if (result != 0) { + ms_error("cannot attach VM"); + return; + } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); + LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); + env->CallVoidMethod(lcData->listener + ,ljb->friendListCreatedId + ,lcData->core + ,getFriendList(env, list)); + handle_possible_java_exception(env, lcData->listener); + } + static void friendListRemoved(LinphoneCore *lc, LinphoneFriendList *list) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + if (result != 0) { + ms_error("cannot attach VM"); + return; + } + + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); + LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); + env->CallVoidMethod(lcData->listener + ,ljb->friendListRemovedId + ,lcData->core + ,getFriendList(env, list)); + handle_possible_java_exception(env, lcData->listener); + } private: static inline void handle_possible_java_exception(JNIEnv *env, jobject listener) diff --git a/java/common/org/linphone/core/LinphoneCoreListener.java b/java/common/org/linphone/core/LinphoneCoreListener.java index b7457a777..0d96e6a0c 100644 --- a/java/common/org/linphone/core/LinphoneCoreListener.java +++ b/java/common/org/linphone/core/LinphoneCoreListener.java @@ -226,5 +226,19 @@ public interface LinphoneCoreListener { * @param info Additional information: error message in case of error state, URL of uploaded file in case of success. */ void uploadStateChanged(LinphoneCore lc, LinphoneCore.LogCollectionUploadState state, String info); + + /** + * Callback prototype for reporting LinphoneFriendList creation. + * @param lc LinphoneCore object + * @param list LinphoneFriendList object + */ + void friendListCreated(LinphoneCore lc, LinphoneFriendList list); + + /** + * Callback prototype for reporting LinphoneFriendList removal. + * @param lc LinphoneCore object + * @param list LinphoneFriendList object + */ + void friendListRemoved(LinphoneCore lc, LinphoneFriendList list); } diff --git a/java/common/org/linphone/core/LinphoneCoreListenerBase.java b/java/common/org/linphone/core/LinphoneCoreListenerBase.java index a7db59c11..772719ad3 100644 --- a/java/common/org/linphone/core/LinphoneCoreListenerBase.java +++ b/java/common/org/linphone/core/LinphoneCoreListenerBase.java @@ -198,4 +198,15 @@ public class LinphoneCoreListenerBase implements LinphoneCoreListener { } + @Override + public void friendListCreated(LinphoneCore lc, LinphoneFriendList list) { + // TODO Auto-generated method stub + + } + + @Override + public void friendListRemoved(LinphoneCore lc, LinphoneFriendList list) { + // TODO Auto-generated method stub + + } } From 64fc5a95946c75fe3033104fcfc9e0f33d1bc448 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 1 Feb 2016 16:30:36 +0100 Subject: [PATCH 092/121] Added JNI wrapper for linphone_friend_list_set_uri and linphone_friend_list_synchronize_friends_from_server --- coreapi/linphonecore_jni.cc | 10 ++++++++++ .../org/linphone/core/LinphoneFriendList.java | 2 ++ .../linphone/core/LinphoneFriendListImpl.java | 16 ++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 02cd5325d..67e76792c 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -3188,6 +3188,16 @@ extern "C" jlong Java_org_linphone_core_LinphoneFriendListImpl_newLinphoneFriend return (jlong)fl; } +extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_setUri(JNIEnv* env, jobject thiz, jlong list, jstring juri) { + const char* uri = env->GetStringUTFChars(juri, NULL); + linphone_friend_list_set_uri((LinphoneFriendList*)list, uri); + env->ReleaseStringUTFChars(juri, uri); +} + +extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_synchronizeFriendsFromServer(JNIEnv* env, jobject thiz, jlong list) { + linphone_friend_list_synchronize_friends_from_server((LinphoneFriendList*)list); +} + extern "C" void Java_org_linphone_core_LinphoneFriendImpl_setAddress(JNIEnv* env ,jobject thiz ,jlong ptr diff --git a/java/common/org/linphone/core/LinphoneFriendList.java b/java/common/org/linphone/core/LinphoneFriendList.java index 29621eb0a..836a99d70 100644 --- a/java/common/org/linphone/core/LinphoneFriendList.java +++ b/java/common/org/linphone/core/LinphoneFriendList.java @@ -24,5 +24,7 @@ public interface LinphoneFriendList { public void addFriend(LinphoneFriend friend); public void updateSubscriptions(LinphoneProxyConfig proxyConfig,boolean onlyWhenRegistered); public LinphoneFriend findFriendByUri(String uri); + public void setUri(String uri); + public void synchronizeFriendsFromServer(); long getNativePtr(); } diff --git a/java/impl/org/linphone/core/LinphoneFriendListImpl.java b/java/impl/org/linphone/core/LinphoneFriendListImpl.java index 19eb2687c..a16a509a9 100644 --- a/java/impl/org/linphone/core/LinphoneFriendListImpl.java +++ b/java/impl/org/linphone/core/LinphoneFriendListImpl.java @@ -66,6 +66,22 @@ class LinphoneFriendListImpl implements LinphoneFriendList, Serializable { } } + private native void setUri(long nativePtr, String uri); + @Override + public void setUri(String uri) { + synchronized(getSyncObject()) { + return setUri(nativePtr, uri); + } + } + + private native void synchronizeFriendsFromServer(long nativePtr); + @Override + public void synchronizeFriendsFromServer() { + synchronized(getSyncObject()) { + synchronizeFriendsFromServer(nativePtr); + } + } + /*reserved for JNI */ protected LinphoneFriendListImpl(long aNativePtr) { From e29cab555d1dc0f1ae11b4eea9a511c1acbde1d3 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 1 Feb 2016 16:49:00 +0100 Subject: [PATCH 093/121] Updated Java tutorials + fixed typo --- .../core/tutorials/TutorialBuddyStatus.java | 13 +++++++++++++ .../linphone/core/tutorials/TutorialChatRoom.java | 12 ++++++++++++ .../core/tutorials/TutorialHelloWorld.java | 12 ++++++++++++ .../core/tutorials/TutorialRegistration.java | 14 ++++++++++++++ .../org/linphone/core/LinphoneFriendListImpl.java | 2 +- 5 files changed, 52 insertions(+), 1 deletion(-) diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java index 82a094183..b5f1475ae 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java @@ -335,4 +335,17 @@ public class TutorialBuddyStatus implements LinphoneCoreListener { // TODO Auto-generated method stub } + + @Override + public void friendListCreated(LinphoneCore lc, LinphoneFriendList list) { + // TODO Auto-generated method stub + + } + + @Override + public void friendListRemoved(LinphoneCore lc, LinphoneFriendList list) { + // TODO Auto-generated method stub + + } + } diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java index 11e436213..f53cd4258 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java @@ -251,5 +251,17 @@ public class TutorialChatRoom implements LinphoneCoreListener, LinphoneChatMessa } + + @Override + public void friendListCreated(LinphoneCore lc, LinphoneFriendList list) { + // TODO Auto-generated method stub + + } + + @Override + public void friendListRemoved(LinphoneCore lc, LinphoneFriendList list) { + // TODO Auto-generated method stub + + } } diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java index 3fc9b78c5..edfaf3a16 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java @@ -257,5 +257,17 @@ public class TutorialHelloWorld implements LinphoneCoreListener { } + + @Override + public void friendListCreated(LinphoneCore lc, LinphoneFriendList list) { + // TODO Auto-generated method stub + + } + + @Override + public void friendListRemoved(LinphoneCore lc, LinphoneFriendList list) { + // TODO Auto-generated method stub + + } } diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java index 5a2db2568..22991e7b1 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java @@ -286,4 +286,18 @@ public class TutorialRegistration implements LinphoneCoreListener { // TODO Auto-generated method stub } + + + @Override + public void friendListCreated(LinphoneCore lc, LinphoneFriendList list) { + // TODO Auto-generated method stub + + } + + @Override + public void friendListRemoved(LinphoneCore lc, LinphoneFriendList list) { + // TODO Auto-generated method stub + + } + } diff --git a/java/impl/org/linphone/core/LinphoneFriendListImpl.java b/java/impl/org/linphone/core/LinphoneFriendListImpl.java index a16a509a9..47dcfea44 100644 --- a/java/impl/org/linphone/core/LinphoneFriendListImpl.java +++ b/java/impl/org/linphone/core/LinphoneFriendListImpl.java @@ -70,7 +70,7 @@ class LinphoneFriendListImpl implements LinphoneFriendList, Serializable { @Override public void setUri(String uri) { synchronized(getSyncObject()) { - return setUri(nativePtr, uri); + setUri(nativePtr, uri); } } From cb657fffbebe62c8df797181e20faa67b1d98f1a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 1 Feb 2016 16:53:48 +0100 Subject: [PATCH 094/121] Forgot import for LinphoneFriendList symbol --- .../java/org/linphone/core/tutorials/TutorialBuddyStatus.java | 1 + .../help/java/org/linphone/core/tutorials/TutorialChatRoom.java | 1 + .../java/org/linphone/core/tutorials/TutorialHelloWorld.java | 1 + .../java/org/linphone/core/tutorials/TutorialRegistration.java | 1 + 4 files changed, 4 insertions(+) diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java index b5f1475ae..654fdea87 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java @@ -38,6 +38,7 @@ import org.linphone.core.LinphoneCoreFactory; import org.linphone.core.LinphoneCoreListener; import org.linphone.core.LinphoneEvent; import org.linphone.core.LinphoneFriend; +import org.linphone.core.LinphoneFriendList; import org.linphone.core.LinphoneFriend.SubscribePolicy; import org.linphone.core.LinphoneInfoMessage; import org.linphone.core.LinphoneProxyConfig; diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java index f53cd4258..ae6f441c8 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java @@ -38,6 +38,7 @@ import org.linphone.core.LinphoneCoreFactory; import org.linphone.core.LinphoneCoreListener; import org.linphone.core.LinphoneEvent; import org.linphone.core.LinphoneFriend; +import org.linphone.core.LinphoneFriendList; import org.linphone.core.LinphoneInfoMessage; import org.linphone.core.LinphoneProxyConfig; import org.linphone.core.PublishState; diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java index edfaf3a16..883d3fb01 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java @@ -38,6 +38,7 @@ import org.linphone.core.LinphoneCoreFactory; import org.linphone.core.LinphoneCoreListener; import org.linphone.core.LinphoneEvent; import org.linphone.core.LinphoneFriend; +import org.linphone.core.LinphoneFriendList; import org.linphone.core.LinphoneInfoMessage; import org.linphone.core.LinphoneProxyConfig; import org.linphone.core.PublishState; diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java index 22991e7b1..cbf9c482f 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java @@ -38,6 +38,7 @@ import org.linphone.core.LinphoneCoreFactory; import org.linphone.core.LinphoneCoreListener; import org.linphone.core.LinphoneEvent; import org.linphone.core.LinphoneFriend; +import org.linphone.core.LinphoneFriendList; import org.linphone.core.LinphoneInfoMessage; import org.linphone.core.LinphoneProxyConfig; import org.linphone.core.PublishState; From 7aedeaacb268e0d2dfb141a2f4709055f9a3d2fd Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 1 Feb 2016 16:59:46 +0100 Subject: [PATCH 095/121] Added missing linphone_friend_list_get_core method --- coreapi/friendlist.c | 4 ++++ coreapi/friendlist.h | 11 +++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index 24e4cf11b..7aa70ca3d 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -688,3 +688,7 @@ void linphone_friend_list_subscription_state_changed(LinphoneCore *lc, LinphoneE } } } + +LinphoneCore* linphone_friend_list_get_core(LinphoneFriendList *list) { + return list->lc; +} diff --git a/coreapi/friendlist.h b/coreapi/friendlist.h index 1bc643139..21a760edf 100644 --- a/coreapi/friendlist.h +++ b/coreapi/friendlist.h @@ -313,17 +313,24 @@ LINPHONE_PUBLIC LinphoneFriendListContactUpdatedCb linphone_friend_list_cbs_get_ LINPHONE_PUBLIC void linphone_friend_list_cbs_set_contact_updated(LinphoneFriendListCbs *cbs, LinphoneFriendListContactUpdatedCb cb); /** - * + * Starts a CardDAV synchronization using value set using linphone_friend_list_set_uri. * @param[in] list LinphoneFriendList object. */ LINPHONE_PUBLIC void linphone_friend_list_synchronize_friends_from_server(LinphoneFriendList *list); /** - * + * Goes through all the LinphoneFriend that are dirty and does a CardDAV PUT to update the server. * @param[in] list LinphoneFriendList object. */ void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list); +/** + * Returns the LinphoneCore object attached to this LinphoneFriendList. + * @param[in] list LinphoneFriendList object. + * @return a LinphoneCore object + */ +LINPHONE_PUBLIC LinphoneCore* linphone_friend_list_get_core(LinphoneFriendList *list); + /** * @} */ From a2b8ff8a6fa54b87e2c1d2e2d872422dcd077b7b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Feb 2016 11:23:03 +0100 Subject: [PATCH 096/121] Added LinphoneFriendList callbacks into JNI layer --- coreapi/linphonecore_jni.cc | 92 ++++++++++++++++++- .../org/linphone/core/LinphoneFriendList.java | 18 +++- .../linphone/core/LinphoneFriendListImpl.java | 9 +- 3 files changed, 112 insertions(+), 7 deletions(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 67e76792c..daf3ad2e4 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -2058,7 +2058,15 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_removeFriendList(JNIEnv* ,jlong lc ,jlong friendList ) { - linphone_core_remove_friend_list((LinphoneCore*)lc,(LinphoneFriendList*)friendList); + LinphoneFriendList *list = (LinphoneFriendList *)friendList; + LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(list); + if (cbs != NULL) { + jobject listener = (jobject) linphone_friend_list_cbs_get_user_data(cbs); + if (listener != NULL) { + env->DeleteGlobalRef(listener); + } + } + linphone_core_remove_friend_list((LinphoneCore*)lc, list); } extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getFriendList(JNIEnv* env @@ -3198,6 +3206,88 @@ extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_synchronizeFriends linphone_friend_list_synchronize_friends_from_server((LinphoneFriendList*)list); } +static void contact_created(LinphoneFriendList *list, LinphoneFriend *lf) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + if (result != 0) { + ms_error("cannot attach VM\n"); + return; + } + + LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(list); + jobject listener = (jobject) linphone_friend_list_cbs_get_user_data(cbs); + + if (listener == NULL) { + ms_error("contact_created() notification without listener"); + return ; + } + jclass clazz = (jclass) env->GetObjectClass(listener); + jmethodID method = env->GetMethodID(clazz, "onLinphoneFriendCreated","(Lorg/linphone/core/LinphoneFriendList;Lorg/linphone/core/LinphoneFriend;)V"); + jobject jlist = getFriendList(env, list); + jobject jfriend = getFriend(env, lf); + env->DeleteLocalRef(clazz); + env->CallVoidMethod(listener, method, jlist, jfriend); +} + +static void contact_updated(LinphoneFriendList *list, LinphoneFriend *lf_new, LinphoneFriend *lf_old) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + if (result != 0) { + ms_error("cannot attach VM\n"); + return; + } + + LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(list); + jobject listener = (jobject) linphone_friend_list_cbs_get_user_data(cbs); + + if (listener == NULL) { + ms_error("contact_updated() notification without listener"); + return ; + } + jclass clazz = (jclass) env->GetObjectClass(listener); + jmethodID method = env->GetMethodID(clazz, "onLinphoneFriendUpdated","(Lorg/linphone/core/LinphoneFriendList;Lorg/linphone/core/LinphoneFriend;Lorg/linphone/core/LinphoneFriend;)V"); + jobject jlist = getFriendList(env, list); + jobject jfriend_new = getFriend(env, lf_new); + jobject jfriend_old = getFriend(env, lf_old); + env->DeleteLocalRef(clazz); + env->CallVoidMethod(listener, method, jlist, jfriend_new, jfriend_old); +} + +static void contact_removed(LinphoneFriendList *list, LinphoneFriend *lf) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + if (result != 0) { + ms_error("cannot attach VM\n"); + return; + } + + LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(list); + jobject listener = (jobject) linphone_friend_list_cbs_get_user_data(cbs); + + if (listener == NULL) { + ms_error("contact_removed() notification without listener"); + return ; + } + jclass clazz = (jclass) env->GetObjectClass(listener); + jmethodID method = env->GetMethodID(clazz, "onLinphoneFriendDeleted","(Lorg/linphone/core/LinphoneFriendList;Lorg/linphone/core/LinphoneFriend;)V"); + jobject jlist = getFriendList(env, list); + jobject jfriend = getFriend(env, lf); + env->DeleteLocalRef(clazz); + env->CallVoidMethod(listener, method, jlist, jfriend); +} + +extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_setListener(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) { + jobject listener = env->NewGlobalRef(jlistener); + LinphoneFriendList *list = (LinphoneFriendList *)ptr; + LinphoneFriendListCbs *cbs; + + cbs = linphone_friend_list_get_callbacks(list); + linphone_friend_list_cbs_set_user_data(cbs, listener); + linphone_friend_list_cbs_set_contact_created(cbs, contact_created); + linphone_friend_list_cbs_set_contact_updated(cbs, contact_updated); + linphone_friend_list_cbs_set_contact_deleted(cbs, contact_removed); +} + extern "C" void Java_org_linphone_core_LinphoneFriendImpl_setAddress(JNIEnv* env ,jobject thiz ,jlong ptr diff --git a/java/common/org/linphone/core/LinphoneFriendList.java b/java/common/org/linphone/core/LinphoneFriendList.java index 836a99d70..eedadfaad 100644 --- a/java/common/org/linphone/core/LinphoneFriendList.java +++ b/java/common/org/linphone/core/LinphoneFriendList.java @@ -18,13 +18,25 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone.core; - public interface LinphoneFriendList { - public void setRLSUri(String uri); + public void setRLSUri(String uri); public void addFriend(LinphoneFriend friend); public void updateSubscriptions(LinphoneProxyConfig proxyConfig,boolean onlyWhenRegistered); public LinphoneFriend findFriendByUri(String uri); public void setUri(String uri); public void synchronizeFriendsFromServer(); - long getNativePtr(); + long getNativePtr(); + + /** + * Set the callbacks associated with the LinphoneFriendList. + */ + void setListener(LinphoneFriendList.LinphoneFriendListListener listener); + + interface LinphoneFriendListListener { + void onLinphoneFriendCreated(LinphoneFriendList list, LinphoneFriend lf); + + void onLinphoneFriendUpdated(LinphoneFriendList list, LinphoneFriend newFriend, LinphoneFriend oldFriend); + + void onLinphoneFriendDeleted(LinphoneFriendList list, LinphoneFriend lf); + } } diff --git a/java/impl/org/linphone/core/LinphoneFriendListImpl.java b/java/impl/org/linphone/core/LinphoneFriendListImpl.java index 47dcfea44..3ec8a6efd 100644 --- a/java/impl/org/linphone/core/LinphoneFriendListImpl.java +++ b/java/impl/org/linphone/core/LinphoneFriendListImpl.java @@ -19,7 +19,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. package org.linphone.core; import java.io.Serializable; -import org.linphone.core.LinphoneProxyConfigImpl; class LinphoneFriendListImpl implements LinphoneFriendList, Serializable { @@ -31,8 +30,7 @@ class LinphoneFriendListImpl implements LinphoneFriendList, Serializable { private native void updateSubscriptions(long nativePtr,long proxyConfigPtr,boolean onlyWhenRegistered); private native Object getCore(long ptr); private native LinphoneFriend findFriendByUri(long nativePtr,String uri); - - + private native void setListener(long ptr, LinphoneFriendListListener listener); protected LinphoneFriendListImpl(LinphoneCoreImpl core) { nativePtr = newLinphoneFriendList(core.nativePtr); @@ -82,6 +80,11 @@ class LinphoneFriendListImpl implements LinphoneFriendList, Serializable { } } + @Override + public void setListener(LinphoneFriendListListener listener) { + setListener(nativePtr, listener); + } + /*reserved for JNI */ protected LinphoneFriendListImpl(long aNativePtr) { From 4100ca07bf59424822163d407e53d006b5281ac2 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Feb 2016 11:54:30 +0100 Subject: [PATCH 097/121] Added a fake test to ensure the addressbook contains the correct values for the VCard test suite --- tester/vcard_tester.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 931e318b7..b40e8edaf 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -475,7 +475,7 @@ static void carddav_integration(void) { BC_ASSERT_EQUAL_FATAL(linphone_friend_list_import_friend(lfl, lf, FALSE), LinphoneFriendListOK, int, "%d"); linphone_friend_unref(lf); - lvc2 = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sberfini.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n"); + lvc2 = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sberfini@sip.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n"); linphone_vcard_set_url(lvc2, "/sabredav/addressbookserver.php/addressbooks/sylvain/default/me.vcf"); lf2 = linphone_friend_new_from_vcard(lvc2); linphone_friend_set_ref_key(lf2, refkey); @@ -513,6 +513,46 @@ static void carddav_integration(void) { linphone_core_manager_destroy(manager); } +static void carddav_clean(void) { // This is to ensure the content of the test addressbook is in the correct state for the following tests + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(lfl); + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + MSList *friends = NULL; + LinphoneFriend *lf = NULL; + LinphoneVCard *lvc = NULL; + + linphone_friend_list_cbs_set_user_data(cbs, stats); + linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); + linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); + linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); + linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + + linphone_friend_list_synchronize_friends_from_server(lfl); + wait_for_until(manager->lc, NULL, NULL, 0, 5000); + + friends = ms_list_copy(lfl->friends); + while (friends) { + LinphoneFriend *lf = (LinphoneFriend *)friends->data; + linphone_friend_list_remove_friend(lfl, lf); + wait_for_until(manager->lc, NULL, NULL, 0, 2000); + stats->removed_contact_count = 0; + friends = ms_list_next(friends); + } + + lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sylvain@sip.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n"); + linphone_vcard_set_url(lvc, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default/me.vcf"); + lf = linphone_friend_new_from_vcard(lvc); + linphone_friend_list_add_friend(lfl, lf); + wait_for_until(manager->lc, NULL, NULL, 0, 2000); + + ms_free(stats); + linphone_friend_unref(lf); + linphone_friend_list_unref(lfl); + linphone_core_manager_destroy(manager); +} + #else static void dummy_test(void) { } @@ -527,6 +567,7 @@ test_t vcard_tests[] = { { "Friends storage migration from rc to db", friends_migration }, { "Friends storage in sqlite database", friends_sqlite_storage }, #endif + { "CardDAV clean", carddav_clean }, // This is to ensure the content of the test addressbook is in the correct state for the following tests { "CardDAV synchronization", carddav_sync }, { "CardDAV synchronization 2", carddav_sync_2 }, { "CardDAV synchronization 3", carddav_sync_3 }, From 9c7eb70ef844a152e6e281d9f1907c3852ef5f9d Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Feb 2016 12:08:43 +0100 Subject: [PATCH 098/121] Fixed all contacts deleted issue when doing many syncs + added test for that --- coreapi/carddav.c | 1 + tester/vcard_tester.c | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 964f3f6e6..377bc918f 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -55,6 +55,7 @@ void* linphone_carddav_get_user_data(LinphoneCardDavContext *cdc) { } void linphone_carddav_synchronize(LinphoneCardDavContext *cdc) { + cdc->ctag = cdc->friend_list->revision; linphone_carddav_get_current_ctag(cdc); } diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index b40e8edaf..73860f1c2 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -553,6 +553,30 @@ static void carddav_clean(void) { // This is to ensure the content of the test linphone_core_manager_destroy(manager); } +static void carddav_multiple_sync(void) { + LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(lfl); + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + + linphone_friend_list_cbs_set_user_data(cbs, stats); + linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); + linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); + linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); + linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + + linphone_friend_list_synchronize_friends_from_server(lfl); + wait_for_until(manager->lc, NULL, NULL, 0, 5000); + linphone_friend_list_synchronize_friends_from_server(lfl); + wait_for_until(manager->lc, NULL, NULL, 0, 5000); + linphone_friend_list_synchronize_friends_from_server(lfl); + BC_ASSERT_EQUAL(stats->removed_contact_count, 0, int, "%i"); + + linphone_friend_list_unref(lfl); + linphone_core_manager_destroy(manager); +} + #else static void dummy_test(void) { } @@ -573,6 +597,7 @@ test_t vcard_tests[] = { { "CardDAV synchronization 3", carddav_sync_3 }, { "CardDAV synchronization 4", carddav_sync_4 }, { "CardDAV integration", carddav_integration }, + { "CardDAV multiple synchronizations", carddav_multiple_sync }, #else { "Dummy test", dummy_test } #endif From 7d03d2e00eafd0c7caa7c6523666f4876d6feb7c Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Feb 2016 14:17:37 +0100 Subject: [PATCH 099/121] Added new method to import a LinphoneFriend into a LinphoneFriendList without flagging it as dirty --- coreapi/friendlist.c | 12 ++++++++++-- coreapi/friendlist.h | 13 +++++++++++-- coreapi/linphonecore_jni.cc | 16 ++++++++++++---- .../org/linphone/core/LinphoneFriendList.java | 1 + .../linphone/core/LinphoneFriendListImpl.java | 16 ++++++++++++---- 5 files changed, 46 insertions(+), 12 deletions(-) diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index 7aa70ca3d..7aa1ff71a 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -375,7 +375,7 @@ void linphone_friend_list_set_rls_uri(LinphoneFriendList *list, const char *rls_ } } -LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf) { +static LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf, bool_t synchronize) { if (!list || !lf->uri || lf->friend_list) { if (!list) ms_error("linphone_friend_list_add_friend(): invalid list, null"); @@ -392,11 +392,19 @@ LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *lis ms_warning("Friend %s already in list [%s], ignored.", tmp ? tmp : "unknown", list->display_name); if (tmp) ms_free(tmp); } else { - return linphone_friend_list_import_friend(list, lf, TRUE); + return linphone_friend_list_import_friend(list, lf, synchronize); } return LinphoneFriendListOK; } +LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf) { + return _linphone_friend_list_add_friend(list, lf, TRUE); +} + +LinphoneFriendListStatus linphone_friend_list_add_local_friend(LinphoneFriendList *list, LinphoneFriend *lf) { + return _linphone_friend_list_add_friend(list, lf, FALSE); +} + LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf, bool_t synchronize) { if (!lf->uri || lf->friend_list) { if (!lf->uri) diff --git a/coreapi/friendlist.h b/coreapi/friendlist.h index 21a760edf..e33ff1a4e 100644 --- a/coreapi/friendlist.h +++ b/coreapi/friendlist.h @@ -145,12 +145,21 @@ LINPHONE_PUBLIC const char * linphone_friend_list_get_rls_uri(const LinphoneFrie LINPHONE_PUBLIC void linphone_friend_list_set_rls_uri(LinphoneFriendList *list, const char *rls_uri); /** - * Add a friend to a friend list. + * Add a friend to a friend list. If or when a remote CardDAV server will be attached to the list, the friend will be sent to the server. * @param[in] list LinphoneFriendList object. * @param[in] friend LinphoneFriend object to add to the friend list. * @return LinphoneFriendListOK if successfully added, LinphoneFriendListInvalidFriend if the friend is not valid. **/ -LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *afriend); +LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf); + +/** + * Add a friend to a friend list. The friend will never be sent to a remote CardDAV server. + * Warning! LinphoneFriends added this way will be removed on the next synchronization, and the callback contact_deleted will be called. + * @param[in] list LinphoneFriendList object. + * @param[in] friend LinphoneFriend object to add to the friend list. + * @return LinphoneFriendListOK if successfully added, LinphoneFriendListInvalidFriend if the friend is not valid. +**/ +LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_add_local_friend(LinphoneFriendList *list, LinphoneFriend *lf); /** * Remove a friend from a friend list. diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index daf3ad2e4..51f3d2132 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -2017,6 +2017,7 @@ extern "C" jobject Java_org_linphone_core_LinphoneCoreImpl_getCurrentCall(JNIEnv ) { return getCall(env,linphone_core_get_current_call((LinphoneCore*)lc)); } + extern "C" void Java_org_linphone_core_LinphoneCoreImpl_addFriend(JNIEnv* env ,jobject thiz ,jlong lc @@ -3309,7 +3310,7 @@ extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_setRLSUri(JNIEnv* ,jlong ptr ,jstring jrlsUri) { const char* uri = env->GetStringUTFChars(jrlsUri, NULL); - linphone_friend_list_set_rls_uri((LinphoneFriendList*)ptr,uri); + linphone_friend_list_set_rls_uri((LinphoneFriendList*)ptr, uri); env->ReleaseStringUTFChars(jrlsUri, uri); } @@ -3319,7 +3320,7 @@ extern "C" jlong Java_org_linphone_core_LinphoneFriendListImpl_findFriendByUri(J ,jstring juri) { const char* uri = env->GetStringUTFChars(juri, NULL); LinphoneFriend* lResult; - lResult = linphone_friend_list_find_friend_by_uri((LinphoneFriendList*)friendListptr,uri); + lResult = linphone_friend_list_find_friend_by_uri((LinphoneFriendList*)friendListptr, uri); env->ReleaseStringUTFChars(juri, uri); return (jlong)lResult; } @@ -3328,7 +3329,14 @@ extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_addFriend(JNIEnv* ,jobject thiz ,jlong friendListptr ,jlong friendPtr) { - linphone_friend_list_add_friend((LinphoneFriendList*)friendListptr,(LinphoneFriend*)friendPtr); + linphone_friend_list_add_friend((LinphoneFriendList*)friendListptr, (LinphoneFriend*)friendPtr); +} + +extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_addLocalFriend(JNIEnv* env + ,jobject thiz + ,jlong friendListptr + ,jlong friendPtr) { + linphone_friend_list_add_local_friend((LinphoneFriendList*)friendListptr, (LinphoneFriend*)friendPtr); } extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_updateSubscriptions(JNIEnv* env @@ -3336,7 +3344,7 @@ extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_updateSubscription ,jlong friendListptr ,jlong proxyConfigPtr ,jboolean jonlyWhenRegistered) { - linphone_friend_list_update_subscriptions((LinphoneFriendList*)friendListptr,(LinphoneProxyConfig*)proxyConfigPtr,jonlyWhenRegistered); + linphone_friend_list_update_subscriptions((LinphoneFriendList*)friendListptr, (LinphoneProxyConfig*)proxyConfigPtr, jonlyWhenRegistered); } diff --git a/java/common/org/linphone/core/LinphoneFriendList.java b/java/common/org/linphone/core/LinphoneFriendList.java index eedadfaad..0e5a46c45 100644 --- a/java/common/org/linphone/core/LinphoneFriendList.java +++ b/java/common/org/linphone/core/LinphoneFriendList.java @@ -21,6 +21,7 @@ package org.linphone.core; public interface LinphoneFriendList { public void setRLSUri(String uri); public void addFriend(LinphoneFriend friend); + public void addLocalFriend(LinphoneFriend friend); public void updateSubscriptions(LinphoneProxyConfig proxyConfig,boolean onlyWhenRegistered); public LinphoneFriend findFriendByUri(String uri); public void setUri(String uri); diff --git a/java/impl/org/linphone/core/LinphoneFriendListImpl.java b/java/impl/org/linphone/core/LinphoneFriendListImpl.java index 3ec8a6efd..4afd20756 100644 --- a/java/impl/org/linphone/core/LinphoneFriendListImpl.java +++ b/java/impl/org/linphone/core/LinphoneFriendListImpl.java @@ -25,11 +25,12 @@ class LinphoneFriendListImpl implements LinphoneFriendList, Serializable { protected final long nativePtr; private native void finalize(long nativePtr); private native long newLinphoneFriendList(long corePtr); - private native void setRLSUri(long nativePtr,String uri); - private native void addFriend(long nativePtr,long friendPtr); - private native void updateSubscriptions(long nativePtr,long proxyConfigPtr,boolean onlyWhenRegistered); + private native void setRLSUri(long nativePtr, String uri); + private native void addFriend(long nativePtr, long friendPtr); + private native void addLocalFriend(long nativePtr, long friendPtr); + private native void updateSubscriptions(long nativePtr, long proxyConfigPtr, boolean onlyWhenRegistered); private native Object getCore(long ptr); - private native LinphoneFriend findFriendByUri(long nativePtr,String uri); + private native LinphoneFriend findFriendByUri(long nativePtr, String uri); private native void setListener(long ptr, LinphoneFriendListListener listener); protected LinphoneFriendListImpl(LinphoneCoreImpl core) { @@ -50,6 +51,13 @@ class LinphoneFriendListImpl implements LinphoneFriendList, Serializable { } } + @Override + public void addLocalFriend(LinphoneFriend friend) { + synchronized(getSyncObject()){ + addLocalFriend(nativePtr, friend.getNativePtr()); + } + } + @Override public void updateSubscriptions(LinphoneProxyConfig proxyConfig,boolean onlyWhenRegistered) { synchronized(getSyncObject()){ From 45bcccf4eb04d9acc06a4c9462cd014bbb6bfb51 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Feb 2016 14:47:15 +0100 Subject: [PATCH 100/121] Added methods (and JNI bindings) to get LinphoneFriends from a LinphoneFriendList and LinphoneFriendLists from LinphoneCore --- coreapi/friendlist.c | 4 ++ coreapi/friendlist.h | 7 ++++ coreapi/linphonecore_jni.cc | 40 +++++++++++++++++++ .../org/linphone/core/LinphoneCore.java | 6 +++ .../org/linphone/core/LinphoneFriendList.java | 1 + .../org/linphone/core/LinphoneCoreImpl.java | 5 +++ .../linphone/core/LinphoneFriendListImpl.java | 8 ++++ 7 files changed, 71 insertions(+) diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index 7aa1ff71a..28a85a2ff 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -448,6 +448,10 @@ LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList * return LinphoneFriendListOK; } +const MSList * linphone_friend_list_get_friends(const LinphoneFriendList *list) { + return list->friends; +} + void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list) { LinphoneCardDavContext *cdc = linphone_carddav_context_new(list); MSList *dirty_friends = list->dirty_friends_to_update; diff --git a/coreapi/friendlist.h b/coreapi/friendlist.h index e33ff1a4e..7d907ac61 100644 --- a/coreapi/friendlist.h +++ b/coreapi/friendlist.h @@ -169,6 +169,13 @@ LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_add_local_friend(L **/ LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *afriend); +/** + * Retrieves the list of LinphoneFriend from this LinphoneFriendList. + * @param[in] list LinphoneFriendList object + * @return \mslist{LinphoneFriend} a list of LinphoneFriend + */ +LINPHONE_PUBLIC const MSList * linphone_friend_list_get_friends(const LinphoneFriendList *list); + /** * Find a friend in the friend list using a LinphoneAddress. * @param[in] list LinphoneFriendList object. diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 51f3d2132..a7b8a3c52 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -2089,6 +2089,27 @@ extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getFriendList(JN return jFriends; } + +extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getFriendLists(JNIEnv* env + ,jobject thiz + ,jlong lc) { + const MSList* friends = linphone_core_get_friends_lists((LinphoneCore*)lc); + int friendsSize = ms_list_size(friends); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data((LinphoneCore *)lc); + jobjectArray jFriends = env->NewObjectArray(friendsSize,ljb->friendListClass,NULL); + + for (int i = 0; i < friendsSize; i++) { + LinphoneFriendList* lfriend = (LinphoneFriendList*)friends->data; + jobject jfriend = getFriendList(env,lfriend); + if(jfriend != NULL){ + env->SetObjectArrayElement(jFriends, i, jfriend); + } + friends = friends->next; + } + + return jFriends; +} + extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setPresenceInfo(JNIEnv* env ,jobject thiz ,jlong lc @@ -3339,6 +3360,25 @@ extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_addLocalFriend(JNI linphone_friend_list_add_local_friend((LinphoneFriendList*)friendListptr, (LinphoneFriend*)friendPtr); } +extern "C" jobjectArray Java_org_linphone_core_LinphoneFriendListImpl_getFriendList(JNIEnv* env, jobject thiz, jlong list) { + const MSList* friends = linphone_friend_list_get_friends((LinphoneFriendList *)list); + int friendsSize = ms_list_size(friends); + LinphoneCore *lc = linphone_friend_list_get_core((LinphoneFriendList *)list); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + jobjectArray jFriends = env->NewObjectArray(friendsSize,ljb->friendClass,NULL); + + for (int i = 0; i < friendsSize; i++) { + LinphoneFriend* lfriend = (LinphoneFriend*)friends->data; + jobject jfriend = getFriend(env,lfriend); + if(jfriend != NULL){ + env->SetObjectArrayElement(jFriends, i, jfriend); + } + friends = friends->next; + } + + return jFriends; +} + extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_updateSubscriptions(JNIEnv* env ,jobject thiz ,jlong friendListptr diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index 6afcb11b9..d21d316c9 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -1020,6 +1020,12 @@ public interface LinphoneCore { */ LinphoneFriend[] getFriendList(); + /** + * Get list of LinphoneFriendList + * @return LinphoneFriendList list + */ + LinphoneFriendList[] getFriendLists(); + /** * @brief Set my presence status * @param minutes_away how long in away diff --git a/java/common/org/linphone/core/LinphoneFriendList.java b/java/common/org/linphone/core/LinphoneFriendList.java index 0e5a46c45..a65f84b48 100644 --- a/java/common/org/linphone/core/LinphoneFriendList.java +++ b/java/common/org/linphone/core/LinphoneFriendList.java @@ -22,6 +22,7 @@ public interface LinphoneFriendList { public void setRLSUri(String uri); public void addFriend(LinphoneFriend friend); public void addLocalFriend(LinphoneFriend friend); + public LinphoneFriend[] getFriendList(); public void updateSubscriptions(LinphoneProxyConfig proxyConfig,boolean onlyWhenRegistered); public LinphoneFriend findFriendByUri(String uri); public void setUri(String uri); diff --git a/java/impl/org/linphone/core/LinphoneCoreImpl.java b/java/impl/org/linphone/core/LinphoneCoreImpl.java index feb0716a6..20c36d164 100644 --- a/java/impl/org/linphone/core/LinphoneCoreImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreImpl.java @@ -471,6 +471,11 @@ class LinphoneCoreImpl implements LinphoneCore { public synchronized LinphoneFriend[] getFriendList() { return getFriendList(nativePtr); } + + private native LinphoneFriendList[] getFriendLists(long nativePtr); + public synchronized LinphoneFriendList[] getFriendLists() { + return getFriendLists(nativePtr); + } @SuppressWarnings("deprecation") public synchronized void setPresenceInfo(int minutes_away, String alternative_contact, OnlineStatus status) { diff --git a/java/impl/org/linphone/core/LinphoneFriendListImpl.java b/java/impl/org/linphone/core/LinphoneFriendListImpl.java index 4afd20756..abcb7ebb8 100644 --- a/java/impl/org/linphone/core/LinphoneFriendListImpl.java +++ b/java/impl/org/linphone/core/LinphoneFriendListImpl.java @@ -28,6 +28,7 @@ class LinphoneFriendListImpl implements LinphoneFriendList, Serializable { private native void setRLSUri(long nativePtr, String uri); private native void addFriend(long nativePtr, long friendPtr); private native void addLocalFriend(long nativePtr, long friendPtr); + private native LinphoneFriend[] getFriendList(long nativePtr); private native void updateSubscriptions(long nativePtr, long proxyConfigPtr, boolean onlyWhenRegistered); private native Object getCore(long ptr); private native LinphoneFriend findFriendByUri(long nativePtr, String uri); @@ -58,6 +59,13 @@ class LinphoneFriendListImpl implements LinphoneFriendList, Serializable { } } + @Override + public LinphoneFriend[] getFriendList() { + synchronized(getSyncObject()){ + return getFriendList(nativePtr); + } + } + @Override public void updateSubscriptions(LinphoneProxyConfig proxyConfig,boolean onlyWhenRegistered) { synchronized(getSyncObject()){ From 32ac62bb239a373f05a6031e0559f0060e81b899 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Feb 2016 15:38:52 +0100 Subject: [PATCH 101/121] Deprecated linphone_core_get_friends --- coreapi/linphonefriend.h | 1 + 1 file changed, 1 insertion(+) diff --git a/coreapi/linphonefriend.h b/coreapi/linphonefriend.h index 52afbae69..709b48ef3 100644 --- a/coreapi/linphonefriend.h +++ b/coreapi/linphonefriend.h @@ -374,6 +374,7 @@ LINPHONE_PUBLIC void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneF * Get Buddy list of LinphoneFriend * @param[in] lc #LinphoneCore object * @return \mslist{LinphoneFriend} + * @deprecated use linphone_core_get_friends_lists() or linphone_friend_list_get_friends() instead. */ LINPHONE_PUBLIC const MSList * linphone_core_get_friend_list(const LinphoneCore *lc); From 2e62153e1f17ee9c2f744eb9ee49f2fd0a8b9b4e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Feb 2016 15:40:09 +0100 Subject: [PATCH 102/121] Also deprecated linphone_core_add_friend and linphone_core_remove_friend --- coreapi/linphonefriend.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/coreapi/linphonefriend.h b/coreapi/linphonefriend.h index 709b48ef3..27e8b6ede 100644 --- a/coreapi/linphonefriend.h +++ b/coreapi/linphonefriend.h @@ -353,6 +353,7 @@ LINPHONE_PUBLIC void linphone_core_interpret_friend_uri(LinphoneCore *lc, const * Add a friend to the current buddy list, if \link linphone_friend_enable_subscribes() subscription attribute \endlink is set, a SIP SUBSCRIBE message is sent. * @param lc #LinphoneCore object * @param fr #LinphoneFriend to add + * @deprecated use linphone_friend_list_add_friend() instead. */ LINPHONE_PUBLIC void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *fr); @@ -360,6 +361,7 @@ LINPHONE_PUBLIC void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend * * Removes a friend from the buddy list * @param lc #LinphoneCore object * @param fr #LinphoneFriend to remove + * @deprecated use linphone_friend_list_remove_friend() instead. */ LINPHONE_PUBLIC void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend *fr); From 9cec5641387839ca9394cf4d7b411d676819aec5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Feb 2016 15:59:41 +0100 Subject: [PATCH 103/121] RFC 6352 stipulates in section 10.3 that addressbook-query must have a filter, even an empty one --- coreapi/carddav.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 377bc918f..87aa9eda8 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -627,7 +627,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_addressbook_query(LinphoneC query->context = cdc; query->depth = "1"; query->ifmatch = NULL; - query->body = ""; + query->body = ""; query->method = "REPORT"; query->url = cdc->friend_list->uri; query->type = LinphoneCardDavQueryTypeAddressbookQuery; From 0370aa9e90f381f4cde65fc81fae4db909cd683b Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Feb 2016 17:09:21 +0100 Subject: [PATCH 104/121] Added new callback for synchronization done + fixed small issue: when contact was removed from the server, it was trying to remove it again --- coreapi/carddav.c | 6 +++--- coreapi/friendlist.c | 41 ++++++++++++++++++++++++++++++++++------- coreapi/friendlist.h | 28 ++++++++++++++++++++++++++++ coreapi/private.h | 1 + tester/vcard_tester.c | 42 ++++++++++++++++++++++++++++++++++-------- 5 files changed, 100 insertions(+), 18 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 87aa9eda8..1bd3b3378 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -133,7 +133,7 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * } } ms_list_free(vCards); - linphone_carddav_sync_done(cdc, TRUE, ""); + linphone_carddav_sync_done(cdc, TRUE, NULL); } static MSList* parse_vcards_from_xml_response(const char *body) { @@ -342,7 +342,7 @@ static void process_response_from_carddav_request(void *data, const belle_http_r } linphone_vcard_set_etag(lvc, etag); - linphone_carddav_sync_done(query->context, TRUE, ""); + linphone_carddav_sync_done(query->context, TRUE, NULL); linphone_friend_unref(lf); } else { // For some reason, server didn't return the eTag of the updated/created vCard @@ -362,7 +362,7 @@ static void process_response_from_carddav_request(void *data, const belle_http_r } break; case LinphoneCardDavQueryTypeDelete: - linphone_carddav_sync_done(query->context, TRUE, ""); + linphone_carddav_sync_done(query->context, TRUE, NULL); break; default: ms_error("Unknown request: %i", query->type); diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index 28a85a2ff..df48f116b 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -80,6 +80,14 @@ void linphone_friend_list_cbs_set_contact_updated(LinphoneFriendListCbs *cbs, Li cbs->contact_updated_cb = cb; } +LinphoneFriendListSyncStateChangedCb linphone_friend_list_cbs_get_sync_status_changed(const LinphoneFriendListCbs *cbs) { + return cbs->sync_state_changed_cb; +} + +void linphone_friend_list_cbs_set_sync_status_changed(LinphoneFriendListCbs *cbs, LinphoneFriendListSyncStateChangedCb cb) { + cbs->sync_state_changed_cb = cb; +} + static char * create_resource_list_xml(const LinphoneFriendList *list) { char *xml_content = NULL; MSList *elem; @@ -425,21 +433,30 @@ LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList * return LinphoneFriendListOK; } -static void carddav_done(LinphoneCardDavContext *cdc, bool_t success, const char *msg) { +static void carddav_done(LinphoneCardDavContext *cdc, bool_t success, const char *msg) { + if (cdc && cdc->friend_list->cbs->sync_state_changed_cb) { + cdc->friend_list->cbs->sync_state_changed_cb(cdc->friend_list, success ? LinphoneFriendListSyncSuccessful : LinphoneFriendListSyncFailure, msg); + } linphone_carddav_context_destroy(cdc); } -LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *lf) { +static LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *lf, bool_t remove_from_server) { MSList *elem = ms_list_find(list->friends, lf); - LinphoneCardDavContext *cdc = linphone_carddav_context_new(list); if (elem == NULL) return LinphoneFriendListNonExistentFriend; #ifdef FRIENDS_SQL_STORAGE_ENABLED linphone_core_remove_friend_from_db(lf->lc, lf); #endif - if (cdc) { - cdc->sync_done_cb = carddav_done; - linphone_carddav_delete_vcard(cdc, lf); + if (remove_from_server) { + LinphoneVCard *lvc = linphone_friend_get_vcard(lf); + if (lvc && linphone_vcard_get_uid(lvc)) { + LinphoneCardDavContext *cdc = linphone_carddav_context_new(list); + cdc->sync_done_cb = carddav_done; + if (cdc->friend_list->cbs->sync_state_changed_cb) { + cdc->friend_list->cbs->sync_state_changed_cb(cdc->friend_list, LinphoneFriendListSyncStarted, NULL); + } + linphone_carddav_delete_vcard(cdc, lf); + } } lf->friend_list = NULL; @@ -448,6 +465,10 @@ LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList * return LinphoneFriendListOK; } +LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *lf) { + return _linphone_friend_list_remove_friend(list, lf, TRUE); +} + const MSList * linphone_friend_list_get_friends(const LinphoneFriendList *list) { return list->friends; } @@ -461,6 +482,9 @@ void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list) { while (dirty_friends) { LinphoneFriend *lf = (LinphoneFriend *)dirty_friends->data; if (lf) { + if (cdc->friend_list->cbs->sync_state_changed_cb) { + cdc->friend_list->cbs->sync_state_changed_cb(cdc->friend_list, LinphoneFriendListSyncStarted, NULL); + } linphone_carddav_put_vcard(cdc, lf); } dirty_friends = ms_list_next(dirty_friends); @@ -482,7 +506,7 @@ static void carddav_created(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { static void carddav_removed(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { if (cdc) { LinphoneFriendList *lfl = cdc->friend_list; - linphone_friend_list_remove_friend(lfl, lf); + _linphone_friend_list_remove_friend(lfl, lf, FALSE); if (cdc->friend_list->cbs->contact_deleted_cb) { cdc->friend_list->cbs->contact_deleted_cb(lfl, lf); } @@ -513,6 +537,9 @@ void linphone_friend_list_synchronize_friends_from_server(LinphoneFriendList *li cdc->contact_removed_cb = carddav_removed; cdc->contact_updated_cb = carddav_updated; cdc->sync_done_cb = carddav_done; + if (cdc && cdc->friend_list->cbs->sync_state_changed_cb) { + cdc->friend_list->cbs->sync_state_changed_cb(cdc->friend_list, LinphoneFriendListSyncStarted, NULL); + } linphone_carddav_synchronize(cdc); } } diff --git a/coreapi/friendlist.h b/coreapi/friendlist.h index 7d907ac61..9d24df966 100644 --- a/coreapi/friendlist.h +++ b/coreapi/friendlist.h @@ -49,6 +49,15 @@ typedef enum _LinphoneFriendListStatus { LinphoneFriendListInvalidFriend } LinphoneFriendListStatus; +/** + * Enum describing the status of a CardDAV synchronization + */ +typedef enum _LinphoneFriendListSyncStatus { + LinphoneFriendListSyncStarted, + LinphoneFriendListSyncSuccessful, + LinphoneFriendListSyncFailure +} LinphoneFriendListSyncStatus; + /** * The LinphoneFriendList object representing a list of friends. **/ @@ -252,6 +261,11 @@ typedef void (*LinphoneFriendListContactDeletedCb)(LinphoneFriendList *list, Lin **/ typedef void (*LinphoneFriendListContactUpdatedCb)(LinphoneFriendList *list, LinphoneFriend *new_friend, LinphoneFriend *old_friend); +/** + * Callback used to notify the status of the synchronization has changed +**/ +typedef void (*LinphoneFriendListSyncStateChangedCb)(LinphoneFriendList *list, LinphoneFriendListSyncStatus status, const char *msg); + /** * Get the LinphoneFriendListCbs object associated with a LinphoneFriendList. * @param[in] request LinphoneXmlRpcRequest object @@ -328,6 +342,20 @@ LINPHONE_PUBLIC LinphoneFriendListContactUpdatedCb linphone_friend_list_cbs_get_ **/ LINPHONE_PUBLIC void linphone_friend_list_cbs_set_contact_updated(LinphoneFriendListCbs *cbs, LinphoneFriendListContactUpdatedCb cb); +/** + * Get the sync status changed callback. + * @param[in] cbs LinphoneFriendListCbs object. + * @return The current sync status changedcallback. +**/ +LINPHONE_PUBLIC LinphoneFriendListSyncStateChangedCb linphone_friend_list_cbs_get_sync_status_changed(const LinphoneFriendListCbs *cbs); + +/** + * Set the contact updated callback. + * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] cb The sync status changed to be used. +**/ +LINPHONE_PUBLIC void linphone_friend_list_cbs_set_sync_status_changed(LinphoneFriendListCbs *cbs, LinphoneFriendListSyncStateChangedCb cb); + /** * Starts a CardDAV synchronization using value set using linphone_friend_list_set_uri. * @param[in] list LinphoneFriendList object. diff --git a/coreapi/private.h b/coreapi/private.h index 713a82e8f..f79683b56 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -702,6 +702,7 @@ struct _LinphoneFriendListCbs { LinphoneFriendListContactCreatedCb contact_created_cb; LinphoneFriendListContactDeletedCb contact_deleted_cb; LinphoneFriendListContactUpdatedCb contact_updated_cb; + LinphoneFriendListSyncStateChangedCb sync_state_changed_cb; }; BELLE_SIP_DECLARE_VPTR(LinphoneFriendListCbs); diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 73860f1c2..e1d21343b 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -439,6 +439,15 @@ static void carddav_contact_updated(LinphoneFriendList *list, LinphoneFriend *ne stats->updated_contact_count++; } +static void carddav_sync_status_changed(LinphoneFriendList *list, LinphoneFriendListSyncStatus status, const char *msg) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); + char *state = status == LinphoneFriendListSyncStarted ? "Sync started" : (status == LinphoneFriendListSyncFailure ? "Sync failure" : "Sync successful"); + ms_message("[CardDAV] %s : %s", state, msg); + if (status == LinphoneFriendListSyncFailure || status == LinphoneFriendListSyncSuccessful) { + stats->sync_done_count++; + } +} + static void carddav_integration(void) { LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); @@ -456,30 +465,34 @@ static void carddav_integration(void) { linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); + linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed); linphone_core_add_friend_list(manager->lc, lfl); BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); BC_ASSERT_EQUAL(ms_list_size(lfl->dirty_friends_to_update), 0, int, "%d"); BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); BC_ASSERT_EQUAL(ms_list_size(lfl->dirty_friends_to_update), 1, int, "%d"); - wait_for_until(manager->lc, NULL, NULL, 1, 2000); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); BC_ASSERT_EQUAL(ms_list_size(lfl->dirty_friends_to_update), 0, int, "%d"); BC_ASSERT_PTR_NOT_NULL(linphone_vcard_get_uid(lvc)); linphone_friend_list_remove_friend(lfl, lf); BC_ASSERT_EQUAL(ms_list_size(lfl->friends), 0, int, "%d"); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 2, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i"); linphone_friend_unref(lf); lf = NULL; lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Ghislain Mary\r\nIMPP;TYPE=work:sip:ghislain@sip.linphone.org\r\nEND:VCARD\r\n"); lf = linphone_friend_new_from_vcard(lvc); - BC_ASSERT_EQUAL_FATAL(linphone_friend_list_import_friend(lfl, lf, FALSE), LinphoneFriendListOK, int, "%d"); + BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_local_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); linphone_friend_unref(lf); lvc2 = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sberfini@sip.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n"); linphone_vcard_set_url(lvc2, "/sabredav/addressbookserver.php/addressbooks/sylvain/default/me.vcf"); lf2 = linphone_friend_new_from_vcard(lvc2); linphone_friend_set_ref_key(lf2, refkey); - BC_ASSERT_EQUAL_FATAL(linphone_friend_list_import_friend(lfl, lf2, FALSE), LinphoneFriendListOK, int, "%d"); + BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_local_friend(lfl, lf2), LinphoneFriendListOK, int, "%d"); linphone_friend_unref(lf2); BC_ASSERT_EQUAL(lfl->revision, 0, int, "%i"); @@ -491,6 +504,8 @@ static void carddav_integration(void) { wait_for_until(manager->lc, NULL, &stats->updated_contact_count, 1, 2000); BC_ASSERT_EQUAL(stats->updated_contact_count, 1, int, "%i"); BC_ASSERT_NOT_EQUAL(lfl->revision, 0, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 3, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 3, int, "%i"); BC_ASSERT_EQUAL_FATAL(ms_list_size(lfl->friends), 1, int, "%i"); lf = (LinphoneFriend *)lfl->friends->data; @@ -526,17 +541,22 @@ static void carddav_clean(void) { // This is to ensure the content of the test linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); + linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed); linphone_core_add_friend_list(manager->lc, lfl); linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_friend_list_synchronize_friends_from_server(lfl); - wait_for_until(manager->lc, NULL, NULL, 0, 5000); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + stats->sync_done_count = 0; friends = ms_list_copy(lfl->friends); while (friends) { LinphoneFriend *lf = (LinphoneFriend *)friends->data; linphone_friend_list_remove_friend(lfl, lf); - wait_for_until(manager->lc, NULL, NULL, 0, 2000); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + stats->sync_done_count = 0; stats->removed_contact_count = 0; friends = ms_list_next(friends); } @@ -545,7 +565,8 @@ static void carddav_clean(void) { // This is to ensure the content of the test linphone_vcard_set_url(lvc, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default/me.vcf"); lf = linphone_friend_new_from_vcard(lvc); linphone_friend_list_add_friend(lfl, lf); - wait_for_until(manager->lc, NULL, NULL, 0, 2000); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); ms_free(stats); linphone_friend_unref(lf); @@ -563,14 +584,19 @@ static void carddav_multiple_sync(void) { linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted); linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); + linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed); linphone_core_add_friend_list(manager->lc, lfl); linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_friend_list_synchronize_friends_from_server(lfl); - wait_for_until(manager->lc, NULL, NULL, 0, 5000); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); linphone_friend_list_synchronize_friends_from_server(lfl); - wait_for_until(manager->lc, NULL, NULL, 0, 5000); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 2, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i"); linphone_friend_list_synchronize_friends_from_server(lfl); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 3, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 3, int, "%i"); BC_ASSERT_EQUAL(stats->removed_contact_count, 0, int, "%i"); linphone_friend_list_unref(lfl); From 522e973553cca8f040f82e91739a37a4a7deba2c Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 2 Feb 2016 17:42:16 +0100 Subject: [PATCH 105/121] Added JNI bindings for newly added LinphoneFriendList synchronization callback --- coreapi/linphonecore_jni.cc | 35 ++++++++++++++++ .../org/linphone/core/LinphoneFriendList.java | 40 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index a7b8a3c52..df3c11c63 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -299,6 +299,8 @@ public: friendListCtrId = env->GetMethodID(friendListClass,"", "(J)V"); friendListCreatedId = env->GetMethodID(listenerClass, "friendListCreated", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriendList;)V"); friendListRemovedId = env->GetMethodID(listenerClass, "friendListRemoved", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriendList;)V"); + friendListSyncStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneFriendList$State")); + friendListSyncStateFromIntId = env->GetStaticMethodID(friendListSyncStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneFriendList$State;"); addressClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneAddressImpl")); addressCtrId = env->GetMethodID(addressClass,"", "(J)V"); @@ -339,6 +341,7 @@ public: env->DeleteGlobalRef(chatRoomClass); env->DeleteGlobalRef(friendClass); env->DeleteGlobalRef(friendListClass); + env->DeleteGlobalRef(friendListSyncStateClass); env->DeleteGlobalRef(infoMessageClass); env->DeleteGlobalRef(linphoneEventClass); env->DeleteGlobalRef(subscriptionStateClass); @@ -412,6 +415,8 @@ public: jmethodID friendListCtrId; jmethodID friendListCreatedId; jmethodID friendListRemovedId; + jclass friendListSyncStateClass; + jmethodID friendListSyncStateFromIntId; jclass addressClass; jmethodID addressCtrId; @@ -3298,6 +3303,35 @@ static void contact_removed(LinphoneFriendList *list, LinphoneFriend *lf) { env->CallVoidMethod(listener, method, jlist, jfriend); } +static void sync_status_changed(LinphoneFriendList *list, LinphoneFriendListSyncStatus status, const char *message) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + if (result != 0) { + ms_error("cannot attach VM\n"); + return; + } + + LinphoneFriendListCbs *cbs = linphone_friend_list_get_callbacks(list); + jobject listener = (jobject) linphone_friend_list_cbs_get_user_data(cbs); + + if (listener == NULL) { + ms_error("sync_status_changed() notification without listener"); + return ; + } + jclass clazz = (jclass) env->GetObjectClass(listener); + jmethodID method = env->GetMethodID(clazz, "onLinphoneFriendSyncStatusChanged","(Lorg/linphone/core/LinphoneFriendList;Lorg/linphone/core/LinphoneFriendList$State;Ljava/lang/String;)V"); + jobject jlist = getFriendList(env, list); + env->DeleteLocalRef(clazz); + + LinphoneCore *lc = linphone_friend_list_get_core((LinphoneFriendList *)list); + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); + jstring msg = message ? env->NewStringUTF(message) : NULL; + env->CallVoidMethod(listener, method, jlist, env->CallStaticObjectMethod(ljb->friendListSyncStateClass, ljb->friendListSyncStateFromIntId, (jint)status), msg); + if (msg) { + env->DeleteLocalRef(msg); + } +} + extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_setListener(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) { jobject listener = env->NewGlobalRef(jlistener); LinphoneFriendList *list = (LinphoneFriendList *)ptr; @@ -3308,6 +3342,7 @@ extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_setListener(JNIEnv linphone_friend_list_cbs_set_contact_created(cbs, contact_created); linphone_friend_list_cbs_set_contact_updated(cbs, contact_updated); linphone_friend_list_cbs_set_contact_deleted(cbs, contact_removed); + linphone_friend_list_cbs_set_sync_status_changed(cbs, sync_status_changed); } extern "C" void Java_org_linphone_core_LinphoneFriendImpl_setAddress(JNIEnv* env diff --git a/java/common/org/linphone/core/LinphoneFriendList.java b/java/common/org/linphone/core/LinphoneFriendList.java index a65f84b48..23dec80ef 100644 --- a/java/common/org/linphone/core/LinphoneFriendList.java +++ b/java/common/org/linphone/core/LinphoneFriendList.java @@ -18,6 +18,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone.core; +import java.util.Vector; + +import org.linphone.core.LinphoneChatMessage.State; + public interface LinphoneFriendList { public void setRLSUri(String uri); public void addFriend(LinphoneFriend friend); @@ -40,5 +44,41 @@ public interface LinphoneFriendList { void onLinphoneFriendUpdated(LinphoneFriendList list, LinphoneFriend newFriend, LinphoneFriend oldFriend); void onLinphoneFriendDeleted(LinphoneFriendList list, LinphoneFriend lf); + + void onLinphoneFriendSyncStatusChanged(LinphoneFriendList list, LinphoneFriendList.State status, String message); + } + public static class State { + static private Vector values = new Vector(); + public final int value() { return mValue; } + + private final int mValue; + private final String mStringValue; + + public final static State SyncStarted = new State(0, "SyncStarted"); + public final static State SyncSuccessful = new State(1, "SyncSuccessful"); + public final static State SyncFailure = new State(2, "SyncFailure"); + + private State(int value,String stringValue) { + mValue = value; + values.addElement(this); + mStringValue = stringValue; + } + + public static State fromInt(int value) { + + for (int i = 0; i < values.size(); i++) { + State state = (State) values.elementAt(i); + if (state.mValue == value) return state; + } + throw new RuntimeException("state not found [" + value + "]"); + } + + public String toString() { + return mStringValue; + } + + public int toInt() { + return mValue; + } } } From bfa055251c89d78788bfb46c5a8e0484324c5a7d Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 3 Feb 2016 11:46:25 +0100 Subject: [PATCH 106/121] Fixed invalid read in vcard tester --- tester/vcard_tester.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index e1d21343b..930c06dcc 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -493,7 +493,6 @@ static void carddav_integration(void) { lf2 = linphone_friend_new_from_vcard(lvc2); linphone_friend_set_ref_key(lf2, refkey); BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_local_friend(lfl, lf2), LinphoneFriendListOK, int, "%d"); - linphone_friend_unref(lf2); BC_ASSERT_EQUAL(lfl->revision, 0, int, "%i"); linphone_friend_list_synchronize_friends_from_server(lfl); @@ -511,6 +510,7 @@ static void carddav_integration(void) { lf = (LinphoneFriend *)lfl->friends->data; BC_ASSERT_STRING_EQUAL(lf->refkey, refkey); BC_ASSERT_EQUAL(lf->storage_id, lf2->storage_id, int, "%i"); + linphone_friend_unref(lf2); BC_ASSERT_STRING_EQUAL(linphone_address_as_string_uri_only(lf->uri), "sip:sylvain@sip.linphone.org"); linphone_friend_edit(lf); From f5e86f8f95176f341d3f3f2a4493133f5da54d32 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 3 Feb 2016 12:05:31 +0100 Subject: [PATCH 107/121] Improved a bit the carddav_updated cb in friendlist --- coreapi/carddav.c | 2 ++ coreapi/friendlist.c | 8 ++++---- tester/vcard_tester.c | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 1bd3b3378..0e8b678ad 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -116,6 +116,8 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * lf->subscribe = lf2->subscribe; lf->refkey = ms_strdup(lf2->refkey); lf->presence_received = lf2->presence_received; + lf->lc = lf2->lc; + lf->friend_list = lf2->friend_list; if (cdc->contact_updated_cb) { ms_debug("Contact updated: %s", linphone_friend_get_name(lf)); diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index df48f116b..4320c81de 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -518,14 +518,14 @@ static void carddav_updated(LinphoneCardDavContext *cdc, LinphoneFriend *lf_new, LinphoneFriendList *lfl = cdc->friend_list; MSList *elem = ms_list_find(lfl->friends, lf_old); if (elem) { - lf_old->friend_list = NULL; - linphone_friend_unref(lf_old); - lfl->friends = ms_list_remove_link(lfl->friends, elem); + elem->data = linphone_friend_ref(lf_new); } - linphone_friend_list_import_friend(lfl, lf_new, FALSE); + linphone_core_store_friend_in_db(lf_new->lc, lf_new); + if (cdc->friend_list->cbs->contact_updated_cb) { cdc->friend_list->cbs->contact_updated_cb(lfl, lf_new, lf_old); } + linphone_friend_unref(lf_old); } } diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 930c06dcc..9b7b2c30f 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -436,6 +436,7 @@ static void carddav_contact_deleted(LinphoneFriendList *list, LinphoneFriend *lf static void carddav_contact_updated(LinphoneFriendList *list, LinphoneFriend *new_friend, LinphoneFriend *old_friend) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); + BC_ASSERT_STRING_EQUAL(linphone_vcard_get_full_name(linphone_friend_get_vcard(new_friend)), linphone_vcard_get_full_name(linphone_friend_get_vcard(old_friend))); stats->updated_contact_count++; } From 0676eaf4f1ee8c4e6f087e1fe7ac9f2165bff1c0 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 3 Feb 2016 14:37:34 +0100 Subject: [PATCH 108/121] Removed deprecated methods from vcard tester + updated import/export vCard API --- coreapi/friend.c | 90 ---------------- coreapi/friendlist.c | 100 ++++++++++++++++++ coreapi/friendlist.h | 23 ++++ coreapi/linphonecore_jni.cc | 12 +-- coreapi/linphonefriend.h | 23 ---- gtk/main.c | 6 +- .../org/linphone/core/LinphoneCore.java | 17 --- .../org/linphone/core/LinphoneFriendList.java | 18 ++++ .../org/linphone/core/LinphoneCoreImpl.java | 18 ---- .../linphone/core/LinphoneFriendListImpl.java | 18 ++++ tester/vcard_tester.c | 60 +++++------ 11 files changed, 198 insertions(+), 187 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index 4f245f6a7..d0a162081 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -912,96 +912,6 @@ LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard) { return fr; } -int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char *vcard_file) { - MSList *vcards = linphone_vcard_list_from_vcard4_file(vcard_file); - int count = 0; - -#ifndef VCARD_ENABLED - ms_error("vCard support wasn't enabled at compilation time"); - return -1; -#endif - if (!vcards) { - ms_error("Failed to parse the file %s", vcard_file); - return -1; - } - while (vcards != NULL && vcards->data != NULL) { - LinphoneVCard *vcard = (LinphoneVCard *)vcards->data; - LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); - if (lf) { - if (LinphoneFriendListOK == linphone_friend_list_import_friend(linphone_core_get_default_friend_list(lc), lf, TRUE)) { - count++; - } - linphone_friend_unref(lf); - } else { - linphone_vcard_free(vcard); - } - vcards = ms_list_next(vcards); - } -#ifndef FRIENDS_SQL_STORAGE_ENABLED - linphone_core_write_friends_config(lc); -#endif - return count; -} - -int linphone_core_import_friends_from_vcard4_buffer(LinphoneCore *lc, const char *vcard_buffer) { - MSList *vcards = linphone_vcard_list_from_vcard4_buffer(vcard_buffer); - int count = 0; - -#ifndef VCARD_ENABLED - ms_error("vCard support wasn't enabled at compilation time"); - return -1; -#endif - if (!vcards) { - ms_error("Failed to parse the buffer"); - return -1; - } - while (vcards != NULL && vcards->data != NULL) { - LinphoneVCard *vcard = (LinphoneVCard *)vcards->data; - LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); - if (lf) { - if (LinphoneFriendListOK == linphone_friend_list_import_friend(linphone_core_get_default_friend_list(lc), lf, TRUE)) { - count++; - } - linphone_friend_unref(lf); - } else { - linphone_vcard_free(vcard); - } - vcards = ms_list_next(vcards); - } -#ifndef FRIENDS_SQL_STORAGE_ENABLED - linphone_core_write_friends_config(lc); -#endif - return count; -} - -void linphone_core_export_friends_as_vcard4_file(LinphoneCore *lc, const char *vcard_file) { - FILE *file = NULL; - const MSList *friends = linphone_core_get_friend_list(lc); - - file = fopen(vcard_file, "w"); - if (file == NULL) { - ms_warning("Could not write %s ! Maybe it is read-only. Contacts will not be saved.", vcard_file); - return; - } - -#ifndef VCARD_ENABLED - ms_error("vCard support wasn't enabled at compilation time"); -#endif - while (friends != NULL && friends->data != NULL) { - LinphoneFriend *lf = (LinphoneFriend *)friends->data; - LinphoneVCard *vcard = linphone_friend_get_vcard(lf); - if (vcard) { - const char *vcard_text = linphone_vcard_as_vcard4_string(vcard); - fprintf(file, "%s", vcard_text); - } else { - ms_warning("Couldn't export friend %s because it doesn't have a vCard attached", linphone_address_as_string(linphone_friend_get_address(lf))); - } - friends = ms_list_next(friends); - } - - fclose(file); -} - /*drops all references to the core and unref*/ void _linphone_friend_release(LinphoneFriend *lf){ lf->lc = NULL; diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index 4320c81de..b13ced1f5 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -731,3 +731,103 @@ void linphone_friend_list_subscription_state_changed(LinphoneCore *lc, LinphoneE LinphoneCore* linphone_friend_list_get_core(LinphoneFriendList *list) { return list->lc; } + +int linphone_friend_list_import_friends_from_vcard4_file(LinphoneFriendList *list, const char *vcard_file) { + MSList *vcards = linphone_vcard_list_from_vcard4_file(vcard_file); + int count = 0; + +#ifndef VCARD_ENABLED + ms_error("vCard support wasn't enabled at compilation time"); + return -1; +#endif + if (!vcards) { + ms_error("Failed to parse the file %s", vcard_file); + return -1; + } + if (!list) { + ms_error("Can't import into a NULL list"); + return -1; + } + + while (vcards != NULL && vcards->data != NULL) { + LinphoneVCard *vcard = (LinphoneVCard *)vcards->data; + LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); + if (lf) { + if (LinphoneFriendListOK == linphone_friend_list_import_friend(list, lf, TRUE)) { + count++; + } + linphone_friend_unref(lf); + } else { + linphone_vcard_free(vcard); + } + vcards = ms_list_next(vcards); + } +#ifndef FRIENDS_SQL_STORAGE_ENABLED + linphone_core_write_friends_config(list->lc); +#endif + return count; +} + +int linphone_friend_list_import_friends_from_vcard4_buffer(LinphoneFriendList *list, const char *vcard_buffer) { + MSList *vcards = linphone_vcard_list_from_vcard4_buffer(vcard_buffer); + int count = 0; + +#ifndef VCARD_ENABLED + ms_error("vCard support wasn't enabled at compilation time"); + return -1; +#endif + if (!vcards) { + ms_error("Failed to parse the buffer"); + return -1; + } + if (!list) { + ms_error("Can't import into a NULL list"); + return -1; + } + + while (vcards != NULL && vcards->data != NULL) { + LinphoneVCard *vcard = (LinphoneVCard *)vcards->data; + LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); + if (lf) { + if (LinphoneFriendListOK == linphone_friend_list_import_friend(list, lf, TRUE)) { + count++; + } + linphone_friend_unref(lf); + } else { + linphone_vcard_free(vcard); + } + vcards = ms_list_next(vcards); + } +#ifndef FRIENDS_SQL_STORAGE_ENABLED + linphone_core_write_friends_config(list->lc); +#endif + return count; +} + +void linphone_friend_list_export_friends_as_vcard4_file(LinphoneFriendList *list, const char *vcard_file) { + FILE *file = NULL; + const MSList *friends = linphone_friend_list_get_friends(list); + + file = fopen(vcard_file, "w"); + if (file == NULL) { + ms_warning("Could not write %s ! Maybe it is read-only. Contacts will not be saved.", vcard_file); + return; + } + +#ifndef VCARD_ENABLED + ms_error("vCard support wasn't enabled at compilation time"); +#endif + while (friends != NULL && friends->data != NULL) { + LinphoneFriend *lf = (LinphoneFriend *)friends->data; + LinphoneVCard *vcard = linphone_friend_get_vcard(lf); + if (vcard) { + const char *vcard_text = linphone_vcard_as_vcard4_string(vcard); + fprintf(file, "%s", vcard_text); + } else { + ms_warning("Couldn't export friend %s because it doesn't have a vCard attached", linphone_address_as_string(linphone_friend_get_address(lf))); + } + friends = ms_list_next(friends); + } + + fclose(file); +} diff --git a/coreapi/friendlist.h b/coreapi/friendlist.h index 9d24df966..d5ddafb39 100644 --- a/coreapi/friendlist.h +++ b/coreapi/friendlist.h @@ -375,6 +375,29 @@ void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list); */ LINPHONE_PUBLIC LinphoneCore* linphone_friend_list_get_core(LinphoneFriendList *list); +/** + * Creates and adds LinphoneFriend objects to LinphoneFriendList from a file that contains the vCard(s) to parse + * @param[in] list the LinphoneFriendList object + * @param[in] vcard_file the path to a file that contains the vCard(s) to parse + * @return the amount of linphone friends created + */ +LINPHONE_PUBLIC int linphone_friend_list_import_friends_from_vcard4_file(LinphoneFriendList *list, const char *vcard_file); + +/** + * Creates and adds LinphoneFriend objects to LinphoneFriendList from a buffer that contains the vCard(s) to parse + * @param[in] list the LinphoneFriendList object + * @param[in] vcard_buffer the buffer that contains the vCard(s) to parse + * @return the amount of linphone friends created + */ +LINPHONE_PUBLIC int linphone_friend_list_import_friends_from_vcard4_buffer(LinphoneFriendList *list, const char *vcard_buffer); + +/** + * Creates and export LinphoneFriend objects from LinphoneFriendList to a file using vCard 4 format + * @param[in] list the LinphoneFriendList object + * @param[in] vcard_file the path to a file that will contain the vCards + */ +LINPHONE_PUBLIC void linphone_friend_list_export_friends_as_vcard4_file(LinphoneFriendList *list, const char *vcard_file); + /** * @} */ diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index df3c11c63..cf9ef144c 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -2031,23 +2031,23 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_addFriend(JNIEnv* env linphone_core_add_friend((LinphoneCore*)lc,(LinphoneFriend*)aFriend); } -extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_importFriendsFromVCardFile(JNIEnv* env, jobject thiz, jlong lc, jstring jpath) { +extern "C" jint Java_org_linphone_core_LinphoneFriendListImpl_importFriendsFromVCardFile(JNIEnv* env, jobject thiz, jlong list, jstring jpath) { const char* path = env->GetStringUTFChars(jpath, NULL); - int count = linphone_core_import_friends_from_vcard4_file((LinphoneCore*)lc, path); + int count = linphone_friend_list_import_friends_from_vcard4_file((LinphoneFriendList*)list, path); env->ReleaseStringUTFChars(jpath, path); return count; } -extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_importFriendsFromVCardBuffer(JNIEnv* env, jobject thiz, jlong lc, jstring jbuffer) { +extern "C" jint Java_org_linphone_core_LinphoneFriendListImpl_importFriendsFromVCardBuffer(JNIEnv* env, jobject thiz, jlong list, jstring jbuffer) { const char* buffer = env->GetStringUTFChars(jbuffer, NULL); - int count = linphone_core_import_friends_from_vcard4_buffer((LinphoneCore*)lc, buffer); + int count = linphone_friend_list_import_friends_from_vcard4_buffer((LinphoneFriendList*)list, buffer); env->ReleaseStringUTFChars(jbuffer, buffer); return count; } -extern "C" void Java_org_linphone_core_LinphoneCoreImpl_exportFriendsToVCardFile(JNIEnv* env, jobject thiz, jlong lc, jstring jpath) { +extern "C" void Java_org_linphone_core_LinphoneFriendListImpl_exportFriendsToVCardFile(JNIEnv* env, jobject thiz, jlong list, jstring jpath) { const char* path = env->GetStringUTFChars(jpath, NULL); - linphone_core_export_friends_as_vcard4_file((LinphoneCore*)lc, path); + linphone_friend_list_export_friends_as_vcard4_file((LinphoneFriendList*)list, path); env->ReleaseStringUTFChars(jpath, path); } diff --git a/coreapi/linphonefriend.h b/coreapi/linphonefriend.h index 27e8b6ede..6345945b3 100644 --- a/coreapi/linphonefriend.h +++ b/coreapi/linphonefriend.h @@ -459,29 +459,6 @@ LINPHONE_PUBLIC bool_t linphone_friend_create_vcard(LinphoneFriend *fr, const ch */ LINPHONE_PUBLIC LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard); -/** - * Creates and adds LinphoneFriend objects to LinphoneCore from a file that contains the vCard(s) to parse - * @param[in] lc the LinphoneCore object - * @param[in] vcard_file the path to a file that contains the vCard(s) to parse - * @return the amount of linphone friends created - */ -LINPHONE_PUBLIC int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char *vcard_file); - -/** - * Creates and adds LinphoneFriend objects to LinphoneCore from a buffer that contains the vCard(s) to parse - * @param[in] lc the LinphoneCore object - * @param[in] vcard_buffer the buffer that contains the vCard(s) to parse - * @return the amount of linphone friends created - */ -LINPHONE_PUBLIC int linphone_core_import_friends_from_vcard4_buffer(LinphoneCore *lc, const char *vcard_buffer); - -/** - * Creates and export LinphoneFriend objects from LinphoneCore to a file using vCard 4 format - * @param[in] lc the LinphoneCore object - * @param[in] vcard_file the path to a file that will contain the vCards - */ -LINPHONE_PUBLIC void linphone_core_export_friends_as_vcard4_file(LinphoneCore *lc, const char *vcard_file); - /** * Sets the database filename where friends will be stored. * If the file does not exist, it will be created. diff --git a/gtk/main.c b/gtk/main.c index 367935645..e7904560e 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1843,7 +1843,8 @@ void linphone_gtk_import_contacts(void) { if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { LinphoneCore *lc = linphone_gtk_get_core(); char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - linphone_core_import_friends_from_vcard4_file(lc, filename); + LinphoneFriendList *list = linphone_core_get_default_friend_list(lc); + linphone_friend_list_import_friends_from_vcard4_file(list, filename); g_free(filename); linphone_gtk_show_friends(); } @@ -1858,7 +1859,8 @@ void linphone_gtk_export_contacts(void) { if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { LinphoneCore *lc = linphone_gtk_get_core(); char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - linphone_core_export_friends_as_vcard4_file(lc, filename); + LinphoneFriendList *list = linphone_core_get_default_friend_list(lc); + linphone_friend_list_export_friends_as_vcard4_file(list, filename); g_free(filename); } gtk_widget_destroy(dialog); diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index d21d316c9..7f3a8acf1 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -2270,23 +2270,6 @@ public interface LinphoneCore { */ public int getNortpTimeout(); - /** - * Imports LinphoneFriends from a vCard 4 file - * @return the number of friend imported - **/ - public int importFriendsFromVCardFile(String file); - - /** - * Imports LinphoneFriends from a vCard 4 buffer - * @return the number of friend imported - **/ - public int importFriendsFromVCardBuffer(String buffer); - - /** - * Exports LinphoneFriends to a vCard 4 file - **/ - public void exportFriendsToVCardFile(String file); - /** * This method is called by the application to notify the linphone core library when the SIP network is reachable. * This is for advanced usage, when SIP and RTP layers are required to use different interfaces. diff --git a/java/common/org/linphone/core/LinphoneFriendList.java b/java/common/org/linphone/core/LinphoneFriendList.java index 23dec80ef..71c37e509 100644 --- a/java/common/org/linphone/core/LinphoneFriendList.java +++ b/java/common/org/linphone/core/LinphoneFriendList.java @@ -31,6 +31,24 @@ public interface LinphoneFriendList { public LinphoneFriend findFriendByUri(String uri); public void setUri(String uri); public void synchronizeFriendsFromServer(); + + /** + * Imports LinphoneFriends from a vCard 4 file + * @return the number of friend imported + **/ + public int importFriendsFromVCardFile(String file); + + /** + * Imports LinphoneFriends from a vCard 4 buffer + * @return the number of friend imported + **/ + public int importFriendsFromVCardBuffer(String buffer); + + /** + * Exports LinphoneFriends to a vCard 4 file + **/ + public void exportFriendsToVCardFile(String file); + long getNativePtr(); /** diff --git a/java/impl/org/linphone/core/LinphoneCoreImpl.java b/java/impl/org/linphone/core/LinphoneCoreImpl.java index 20c36d164..382d0f5de 100644 --- a/java/impl/org/linphone/core/LinphoneCoreImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreImpl.java @@ -1625,24 +1625,6 @@ class LinphoneCoreImpl implements LinphoneCore { public int getNortpTimeout(){ return getNortpTimeout(nativePtr); } - - private native int importFriendsFromVCardFile(long nativePtr, String file); - @Override - public int importFriendsFromVCardFile(String file) { - return importFriendsFromVCardFile(nativePtr, file); - } - - private native int importFriendsFromVCardBuffer(long nativePtr, String buffer); - @Override - public int importFriendsFromVCardBuffer(String buffer) { - return importFriendsFromVCardBuffer(nativePtr, buffer); - } - - private native void exportFriendsToVCardFile(long nativePtr, String file); - @Override - public void exportFriendsToVCardFile(String file) { - exportFriendsToVCardFile(nativePtr, file); - } private native void setSipNetworkReachable(long nativePtr, boolean isReachable); @Override diff --git a/java/impl/org/linphone/core/LinphoneFriendListImpl.java b/java/impl/org/linphone/core/LinphoneFriendListImpl.java index abcb7ebb8..58b9ccdb9 100644 --- a/java/impl/org/linphone/core/LinphoneFriendListImpl.java +++ b/java/impl/org/linphone/core/LinphoneFriendListImpl.java @@ -96,6 +96,24 @@ class LinphoneFriendListImpl implements LinphoneFriendList, Serializable { } } + private native int importFriendsFromVCardFile(long nativePtr, String file); + @Override + public int importFriendsFromVCardFile(String file) { + return importFriendsFromVCardFile(nativePtr, file); + } + + private native int importFriendsFromVCardBuffer(long nativePtr, String buffer); + @Override + public int importFriendsFromVCardBuffer(String buffer) { + return importFriendsFromVCardBuffer(nativePtr, buffer); + } + + private native void exportFriendsToVCardFile(long nativePtr, String file); + @Override + public void exportFriendsToVCardFile(String file) { + exportFriendsToVCardFile(nativePtr, file); + } + @Override public void setListener(LinphoneFriendListListener listener) { setListener(nativePtr, listener); diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 9b7b2c30f..d425eb822 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -30,32 +30,26 @@ static char *create_filepath(const char *dir, const char *filename, const char * static void linphone_vcard_import_export_friends_test(void) { LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); + const MSList *friends = linphone_friend_list_get_friends(lfl); char *import_filepath = bc_tester_res("common/vcards.vcf"); char *export_filepath = create_filepath(bc_tester_get_writable_dir_prefix(), "export_vcards", "vcf"); - const MSList *friends = linphone_core_get_friend_list(manager->lc); int count = 0; - LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); - BC_ASSERT_PTR_NOT_NULL_FATAL(linphone_core_get_default_friend_list(manager->lc)); - count = linphone_core_import_friends_from_vcard4_file(manager->lc, import_filepath); + count = linphone_friend_list_import_friends_from_vcard4_file(lfl, import_filepath); BC_ASSERT_EQUAL(count, 3, int, "%d"); - friends = linphone_core_get_friend_list(manager->lc); + friends = linphone_friend_list_get_friends(lfl); BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d"); - linphone_core_export_friends_as_vcard4_file(manager->lc, export_filepath); + linphone_friend_list_export_friends_as_vcard4_file(lfl, export_filepath); - linphone_core_remove_friend_list(manager->lc, linphone_core_get_default_friend_list(manager->lc)); - friends = linphone_core_get_friend_list(manager->lc); - BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); - - linphone_core_add_friend_list(manager->lc, lfl); + lfl = linphone_core_create_friend_list(manager->lc); + count = linphone_friend_list_import_friends_from_vcard4_file(lfl, export_filepath); + BC_ASSERT_EQUAL(count, 3, int, "%d"); + friends = linphone_friend_list_get_friends(lfl); + BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d"); linphone_friend_list_unref(lfl); - lfl = NULL; - count = linphone_core_import_friends_from_vcard4_file(manager->lc, export_filepath); - BC_ASSERT_EQUAL(count, 3, int, "%d"); - friends = linphone_core_get_friend_list(manager->lc); - BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d"); remove(export_filepath); ms_free(import_filepath); @@ -65,16 +59,17 @@ static void linphone_vcard_import_export_friends_test(void) { static void linphone_vcard_import_a_lot_of_friends_test(void) { LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); + LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); char *import_filepath = bc_tester_res("common/thousand_vcards.vcf"); clock_t start, end; double elapsed = 0; const MSList *friends = NULL; start = clock(); - linphone_core_import_friends_from_vcard4_file(manager->lc, import_filepath); + linphone_friend_list_import_friends_from_vcard4_file(lfl, import_filepath); end = clock(); - friends = linphone_core_get_friend_list(manager->lc); + friends = linphone_friend_list_get_friends(lfl); BC_ASSERT_EQUAL(ms_list_size(friends), 482, int, "%i"); // Thousand vcards contains 482 contacts with a SIP URI elapsed = (double)(end - start); @@ -92,18 +87,20 @@ static void friends_if_no_db_set(void) { LinphoneFriend *lf = linphone_friend_new(); LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); const MSList *friends = NULL; + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); linphone_friend_set_address(lf, addr); linphone_friend_set_name(lf, "Sylvain"); - linphone_core_add_friend(manager->lc, lf); - linphone_friend_unref(lf); - friends = linphone_core_get_friend_list(manager->lc); + linphone_friend_list_add_friend(lfl, lf); + friends = linphone_friend_list_get_friends(lfl); BC_ASSERT_EQUAL(ms_list_size(friends), 1, int, "%d"); - linphone_core_remove_friend(manager->lc, lf); - friends = linphone_core_get_friend_list(manager->lc); + linphone_friend_list_remove_friend(lfl, lf); + linphone_friend_unref(lf); + friends = linphone_friend_list_get_friends(lfl); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); + linphone_friend_list_unref(lfl); linphone_address_unref(addr); linphone_core_manager_destroy(manager); } @@ -111,25 +108,26 @@ static void friends_if_no_db_set(void) { #ifdef FRIENDS_SQL_STORAGE_ENABLED static void friends_migration(void) { LinphoneCoreManager* manager = linphone_core_manager_new2("friends_rc", FALSE); - const MSList *friends = linphone_core_get_friend_list(manager->lc); + LinphoneFriendList *lfl = linphone_core_get_default_friend_list(manager->lc); + const MSList *friends = linphone_friend_list_get_friends(lfl); MSList *friends_from_db = NULL; char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); unlink(friends_db); linphone_core_set_friends_database_path(manager->lc, friends_db); - friends = linphone_core_get_friend_list(manager->lc); + friends = linphone_friend_list_get_friends(lfl); BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d"); - friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, linphone_core_get_default_friend_list(manager->lc)); + friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 3, int, "%d"); if (ms_list_size(friends_from_db) < 3) { goto end; } end: + friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); unlink(friends_db); ms_free(friends_db); - friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); linphone_core_manager_destroy(manager); } @@ -165,7 +163,7 @@ static void friends_sqlite_storage(void) { v_table->friend_list_created = friend_list_created_cb; v_table->friend_list_removed = friend_list_removed_cb; lc = linphone_core_new(v_table, NULL, NULL, NULL); - friends = linphone_core_get_friend_list(lc); + friends = linphone_friend_list_get_friends(linphone_core_get_default_friend_list(lc)); lfl = linphone_core_create_friend_list(lc); linphone_friend_list_set_user_data(lfl, stats); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); @@ -191,7 +189,7 @@ static void friends_sqlite_storage(void) { BC_ASSERT_EQUAL(lfl->storage_id, 1, int, "%d"); BC_ASSERT_EQUAL(lf->storage_id, 1, int, "%d"); - friends = linphone_core_get_friend_list(lc); + friends = linphone_friend_list_get_friends(linphone_core_get_default_friend_list(lc)); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); friends_lists_from_db = linphone_core_fetch_friends_lists_from_db(lc); @@ -228,8 +226,8 @@ static void friends_sqlite_storage(void) { BC_ASSERT_STRING_EQUAL(linphone_friend_get_name(lf2), "Margaux"); friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); - linphone_core_remove_friend(lc, lf); - friends = linphone_core_get_friend_list(lc); + linphone_friend_list_remove_friend(lfl, lf); + friends = linphone_friend_list_get_friends(linphone_core_get_default_friend_list(lc)); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); friends_from_db = linphone_core_fetch_friends_from_db(lc, lfl); BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 0, int, "%d"); From d45825823720856e5d3ac644e76818b49c350042 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 3 Feb 2016 15:26:07 +0100 Subject: [PATCH 109/121] Fixed segfault when manipulating friends with vcards without carddav configured --- coreapi/friendlist.c | 10 ++++++---- tester/vcard_tester.c | 4 ---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index b13ced1f5..f7501e2c4 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -451,11 +451,13 @@ static LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFrie LinphoneVCard *lvc = linphone_friend_get_vcard(lf); if (lvc && linphone_vcard_get_uid(lvc)) { LinphoneCardDavContext *cdc = linphone_carddav_context_new(list); - cdc->sync_done_cb = carddav_done; - if (cdc->friend_list->cbs->sync_state_changed_cb) { - cdc->friend_list->cbs->sync_state_changed_cb(cdc->friend_list, LinphoneFriendListSyncStarted, NULL); + if (cdc) { + cdc->sync_done_cb = carddav_done; + if (cdc->friend_list->cbs->sync_state_changed_cb) { + cdc->friend_list->cbs->sync_state_changed_cb(cdc->friend_list, LinphoneFriendListSyncStarted, NULL); + } + linphone_carddav_delete_vcard(cdc, lf); } - linphone_carddav_delete_vcard(cdc, lf); } } diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index d425eb822..cf0dd5964 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -120,11 +120,7 @@ static void friends_migration(void) { BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d"); friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 3, int, "%d"); - if (ms_list_size(friends_from_db) < 3) { - goto end; - } -end: friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); unlink(friends_db); ms_free(friends_db); From 2f9f5451632284704608c6aef243eb3a1387f0bb Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 3 Feb 2016 15:54:36 +0100 Subject: [PATCH 110/121] Added test for import vcards from buffer --- tester/common/thousand_vcards.vcf | 2 +- tester/vcard_tester.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/tester/common/thousand_vcards.vcf b/tester/common/thousand_vcards.vcf index 39552174a..fa5dd84c2 100644 --- a/tester/common/thousand_vcards.vcf +++ b/tester/common/thousand_vcards.vcf @@ -8476,7 +8476,6 @@ BDAY:19840316 EMAIL:kesha.tuggle@essefeugait.org N:Tuggle;Kesha;;; ORG:South Studio Vision -IMPP:sip:kesha@sip.linphone.org FN:Kesha Tuggle TEL:tel:(865)414-7674 END:VCARD @@ -8539,4 +8538,5 @@ N:Kimbrough;Deidra;;; FN:Deidra Kimbrough ORG:Pacific Bell TEL:tel:(413)543-7430 +IMPP:sip:kimbrough@sip.linphone.org END:VCARD diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index cf0dd5964..3107044c2 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -64,6 +64,9 @@ static void linphone_vcard_import_a_lot_of_friends_test(void) { clock_t start, end; double elapsed = 0; const MSList *friends = NULL; + FILE *infile; + char *buffer; + long numbytes; start = clock(); linphone_friend_list_import_friends_from_vcard4_file(lfl, import_filepath); @@ -73,11 +76,36 @@ static void linphone_vcard_import_a_lot_of_friends_test(void) { BC_ASSERT_EQUAL(ms_list_size(friends), 482, int, "%i"); // Thousand vcards contains 482 contacts with a SIP URI elapsed = (double)(end - start); - ms_error("Imported a thousand of vCards (only %i friends with SIP address found) in %f seconds", ms_list_size(friends), elapsed / CLOCKS_PER_SEC); + ms_error("Imported a thousand of vCards from file (only %i friends with SIP address found) in %f seconds", ms_list_size(friends), elapsed / CLOCKS_PER_SEC); #ifndef ANDROID BC_ASSERT_TRUE(elapsed < 1500000); // 1.5 seconds #endif + lfl = linphone_core_create_friend_list(manager->lc); + infile = fopen(import_filepath, "r"); + fseek(infile, 0L, SEEK_END); + numbytes = ftell(infile); + fseek(infile, 0L, SEEK_SET); + buffer = (char*)ms_malloc(numbytes * sizeof(char)); + numbytes = fread(buffer, sizeof(char), numbytes, infile); + fclose(infile); + + start = clock(); + linphone_friend_list_import_friends_from_vcard4_buffer(lfl, buffer); + end = clock(); + + friends = linphone_friend_list_get_friends(lfl); + BC_ASSERT_EQUAL(ms_list_size(friends), 482, int, "%i"); // Thousand vcards contains 482 contacts with a SIP URI + + elapsed = (double)(end - start); + ms_error("Imported a thousand of vCards from buffer (only %i friends with SIP address found) in %f seconds", ms_list_size(friends), elapsed / CLOCKS_PER_SEC); +#ifndef ANDROID + BC_ASSERT_TRUE(elapsed < 1500000); // 1.5 seconds +#endif + + ms_free(buffer); + linphone_friend_list_unref(lfl); + ms_free(import_filepath); linphone_core_manager_destroy(manager); } From c15cfd5f4c3849ea3abbec100994534bae21c35a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 9 Feb 2016 10:21:45 +0100 Subject: [PATCH 111/121] Fix previous merge --- coreapi/private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/private.h b/coreapi/private.h index d598d6524..54364dbc0 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1402,7 +1402,7 @@ BELLE_SIP_TYPE_ID(LinphoneXmlRpcRequest), BELLE_SIP_TYPE_ID(LinphoneXmlRpcRequestCbs), BELLE_SIP_TYPE_ID(LinphoneXmlRpcSession), BELLE_SIP_TYPE_ID(LinphoneTunnelConfig), -BELLE_SIP_TYPE_ID(LinphoneFriendListCbs) +BELLE_SIP_TYPE_ID(LinphoneFriendListCbs), BELLE_SIP_TYPE_ID(LinphoneEvent) BELLE_SIP_DECLARE_TYPES_END From eb9390868895fc37665331b37a3374af5c41e3e5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 9 Feb 2016 14:55:39 +0100 Subject: [PATCH 112/121] Using dav.linphone.org instead of hardcoded ip for CardDAV tests --- tester/rcfiles/carddav_rc | 2 +- tester/vcard_tester.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tester/rcfiles/carddav_rc b/tester/rcfiles/carddav_rc index b5169b5fd..a305fd111 100644 --- a/tester/rcfiles/carddav_rc +++ b/tester/rcfiles/carddav_rc @@ -6,7 +6,7 @@ ping_with_options=0 sip_random_port=1 [auth_info_0] -domain=192.168.0.230 +domain=dav.linphone.org username=sylvain ha1=4747ce2517a985f2fc20234a38f068b6 realm=SabreDAV \ No newline at end of file diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 3107044c2..ed66e234d 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -306,7 +306,7 @@ static void carddav_sync(void) { LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); LinphoneCardDavContext *c = NULL; - linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + linphone_friend_list_set_uri(lfl, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_core_add_friend_list(manager->lc, lfl); linphone_friend_list_unref(lfl); c = linphone_carddav_context_new(lfl); @@ -337,7 +337,7 @@ static void carddav_sync_2(void) { LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); LinphoneCardDavContext *c = NULL; - linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + linphone_friend_list_set_uri(lfl, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_core_add_friend_list(manager->lc, lfl); linphone_friend_list_unref(lfl); c = linphone_carddav_context_new(lfl); @@ -379,7 +379,7 @@ static void carddav_sync_3(void) { LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); LinphoneCardDavContext *c = NULL; - linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + linphone_friend_list_set_uri(lfl, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_core_add_friend_list(manager->lc, lfl); linphone_friend_list_unref(lfl); c = linphone_carddav_context_new(lfl); @@ -418,7 +418,7 @@ static void carddav_sync_4(void) { LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); LinphoneCardDavContext *c = NULL; - linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + linphone_friend_list_set_uri(lfl, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_core_add_friend_list(manager->lc, lfl); linphone_friend_list_unref(lfl); c = linphone_carddav_context_new(lfl); @@ -482,7 +482,7 @@ static void carddav_integration(void) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); const char *refkey = "toto"; - linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + linphone_friend_list_set_uri(lfl, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default"); cbs = linphone_friend_list_get_callbacks(lfl); linphone_friend_list_cbs_set_user_data(cbs, stats); linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created); @@ -566,7 +566,7 @@ static void carddav_clean(void) { // This is to ensure the content of the test linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed); linphone_core_add_friend_list(manager->lc, lfl); - linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + linphone_friend_list_set_uri(lfl, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_friend_list_synchronize_friends_from_server(lfl); wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); @@ -585,7 +585,7 @@ static void carddav_clean(void) { // This is to ensure the content of the test } lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sylvain@sip.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n"); - linphone_vcard_set_url(lvc, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default/me.vcf"); + linphone_vcard_set_url(lvc, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default/me.vcf"); lf = linphone_friend_new_from_vcard(lvc); linphone_friend_list_add_friend(lfl, lf); wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); @@ -609,7 +609,7 @@ static void carddav_multiple_sync(void) { linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated); linphone_friend_list_cbs_set_sync_status_changed(cbs, carddav_sync_status_changed); linphone_core_add_friend_list(manager->lc, lfl); - linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + linphone_friend_list_set_uri(lfl, "http://dav.linphone.org/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_friend_list_synchronize_friends_from_server(lfl); wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); From 5af6553ac11311f81d6fffce5d54a2cfe973bc5e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 18 Feb 2016 16:56:28 +0100 Subject: [PATCH 113/121] Updated ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 19e101d26..34053d67d 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 19e101d26bb39b47e0dd75038e5c68bbff1fc364 +Subproject commit 34053d67d290a5935d4bf1d54264801578c3f9f0 From b6b4985e28dab44b6f8340ac731ecf5e873b7beb Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 25 Feb 2016 14:56:31 +0100 Subject: [PATCH 114/121] Create vCards for friends when migrating from rc to db --- coreapi/friend.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index a2dec42ef..5319d3c41 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -1341,6 +1341,7 @@ void linphone_core_set_friends_database_path(LinphoneCore *lc, const char *path) void linphone_core_migrate_friends_from_rc_to_db(LinphoneCore *lc) { LpConfig *lpc = NULL; LinphoneFriend *lf = NULL; + LinphoneFriendList *lfl = linphone_core_get_default_friend_list(lc); int i; #ifndef FRIENDS_SQL_STORAGE_ENABLED ms_warning("linphone has been compiled without sqlite, can't migrate friends"); @@ -1362,8 +1363,12 @@ void linphone_core_migrate_friends_from_rc_to_db(LinphoneCore *lc) { for (i = 0; (lf = linphone_friend_new_from_config_file(lc, i)) != NULL; i++) { char friend_section[32]; + + if (!linphone_friend_create_vcard(lf, linphone_address_get_username(linphone_friend_get_address(lf)))) { + ms_warning("Couldn't create vCard for friend %s", linphone_address_as_string(linphone_friend_get_address(lf))); + } - linphone_core_add_friend(lc, lf); + linphone_friend_list_add_friend(lfl, lf); linphone_friend_unref(lf); snprintf(friend_section, sizeof(friend_section), "friend_%i", i); From 0b6cc88dde437fee27187332f4d72ea995348ec6 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 25 Feb 2016 16:04:22 +0100 Subject: [PATCH 115/121] Show gtk dialog for windows --- gtk/main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gtk/main.c b/gtk/main.c index e7904560e..c37966f74 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1840,6 +1840,8 @@ void linphone_gtk_show_keypad_checked(GtkCheckMenuItem *check_menu_item) { void linphone_gtk_import_contacts(void) { GtkWidget *mw = linphone_gtk_get_main_window(); GtkWidget *dialog = gtk_file_chooser_dialog_new("Open vCard file", (GtkWindow *)mw, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + + gtk_widget_show(dialog); if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { LinphoneCore *lc = linphone_gtk_get_core(); char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); @@ -1856,6 +1858,7 @@ void linphone_gtk_export_contacts(void) { GtkWidget *dialog = gtk_file_chooser_dialog_new("Save vCards as", (GtkWindow *)mw, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); + gtk_widget_show(dialog); if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { LinphoneCore *lc = linphone_gtk_get_core(); char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); From befbdada932360372a39599e9ea19fc2ca3e6866 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 25 Feb 2016 16:30:55 +0100 Subject: [PATCH 116/121] Fixed Segfault when trying to store friend's vcard in db before it was added to a friendlist --- coreapi/friend.c | 5 +++++ gtk/friendlist.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index 5319d3c41..5e448c66f 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -1133,6 +1133,11 @@ void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) { return; } + if (!lf || !lf->friend_list) { + ms_warning("Either the friend or the friend list is null, skipping..."); + return; + } + if (lf->friend_list->storage_id == 0) { ms_warning("Trying to add a friend in db, but friend list isn't, let's do that first"); linphone_core_store_friends_list_in_db(lc, lf->friend_list); diff --git a/gtk/friendlist.c b/gtk/friendlist.c index 3d51e0459..5a7c29c46 100644 --- a/gtk/friendlist.c +++ b/gtk/friendlist.c @@ -440,7 +440,7 @@ static void icon_press_handler(GtkEntry *entry){ lf=linphone_core_get_friend_by_address(linphone_gtk_get_core(),uri); ms_free(uri); if (lf==NULL) - lf=linphone_friend_new(); + lf=linphone_core_create_friend(linphone_gtk_get_core()); if (lf!=NULL){ linphone_friend_set_address(lf,addr); linphone_gtk_show_contact(lf, w); @@ -752,7 +752,7 @@ void linphone_gtk_contact_ok(GtkWidget *button){ const gchar *name,*uri; LinphoneAddress* friend_address; if (lf==NULL){ - lf=linphone_friend_new(); + lf=linphone_core_create_friend(linphone_gtk_get_core()); if (linphone_gtk_get_ui_config_int("use_subscribe_notify",1)==1){ show_presence=FALSE; allow_presence=FALSE; From 7d6c8ca00e7cdc946e73d7b981579bf119927ef9 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 25 Feb 2016 17:08:13 +0100 Subject: [PATCH 117/121] This should fix export issue on win32 --- coreapi/friendlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index 039917bfe..49485736c 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -815,7 +815,7 @@ void linphone_friend_list_export_friends_as_vcard4_file(LinphoneFriendList *list FILE *file = NULL; const MSList *friends = linphone_friend_list_get_friends(list); - file = fopen(vcard_file, "w"); + file = fopen(vcard_file, "wb"); if (file == NULL) { ms_warning("Could not write %s ! Maybe it is read-only. Contacts will not be saved.", vcard_file); return; From 456de10d65aa9f1464bbbd3f928107cf1e5909d3 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 26 Feb 2016 13:56:18 +0100 Subject: [PATCH 118/121] Added back std c++11 when building vcard --- coreapi/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index f11730383..52f516fd8 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -177,6 +177,7 @@ endif() if(BELCARD_FOUND) list(APPEND LIBS ${BELCARD_LIBRARIES}) list(APPEND LINPHONE_SOURCE_FILES_CXX vcard.cc) + list(APPEND STRICT_OPTIONS_CXX "-std=c++11") else() list(APPEND LINPHONE_SOURCE_FILES_C vcard_stubs.c) endif() From 5470a63128e298136f679b55f4a19f00c618a4b1 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 2 Mar 2016 10:41:45 +0100 Subject: [PATCH 119/121] Added simple test to assert vcard creation on edit --- tester/vcard_tester.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index ed66e234d..0a1bbd294 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -110,6 +110,20 @@ static void linphone_vcard_import_a_lot_of_friends_test(void) { linphone_core_manager_destroy(manager); } +static void linphone_vcard_update_existing_friends_test(void) { + LinphoneFriend *lf = linphone_friend_new_with_addr("sip:oldfriend@sip.linphone.org"); + + BC_ASSERT_PTR_NOT_NULL_FATAL(lf); + BC_ASSERT_PTR_NULL(linphone_friend_get_vcard(lf)); + + linphone_friend_edit(lf); + linphone_friend_set_name(lf, "Old Friend"); + linphone_friend_done(lf); + + BC_ASSERT_PTR_NOT_NULL(linphone_friend_get_vcard(lf)); + BC_ASSERT_STRING_EQUAL(linphone_vcard_get_full_name(linphone_friend_get_vcard(lf)), "Old Friend"); +} + static void friends_if_no_db_set(void) { LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); LinphoneFriend *lf = linphone_friend_new(); @@ -635,6 +649,7 @@ test_t vcard_tests[] = { #ifdef VCARD_ENABLED { "Import / Export friends from vCards", linphone_vcard_import_export_friends_test }, { "Import a lot of friends from vCards", linphone_vcard_import_a_lot_of_friends_test }, + { "vCard creation for existing friends", linphone_vcard_update_existing_friends_test }, #ifdef FRIENDS_SQL_STORAGE_ENABLED { "Friends working if no db set", friends_if_no_db_set }, { "Friends storage migration from rc to db", friends_migration }, From 3b3ad2b684e863f487bb76e2d8eec4cca2c62681 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 2 Mar 2016 10:53:43 +0100 Subject: [PATCH 120/121] Fixed tester Makefile.am --- tester/Makefile.am | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tester/Makefile.am b/tester/Makefile.am index 3d1a18c7c..e60cc7433 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -74,7 +74,7 @@ RCFILES = \ IMAGE_FILES = images/nowebcamCIF.jpg -COMMON_FILE = common/bc_completion common/vcards.vcf common/thousand_vcards.vcf +COMMON_FILE = common/vcards.vcf common/thousand_vcards.vcf EXTRA_DIST = tester_hosts\ messages.db\ @@ -136,8 +136,7 @@ liblinphonetester_la_SOURCES = \ tester.c \ upnp_tester.c \ video_tester.c \ - vcard_tester.c \ - common/bc_tester_utils.c + vcard_tester.c liblinphonetester_ladir = $(includedir)/linphone From a3290da40087330dbb4ddbc0a7febc34973baf48 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 3 Mar 2016 11:07:22 +0100 Subject: [PATCH 121/121] Fixed latest vcard test leak --- tester/vcard_tester.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 0a1bbd294..2d25ecffa 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -122,6 +122,8 @@ static void linphone_vcard_update_existing_friends_test(void) { BC_ASSERT_PTR_NOT_NULL(linphone_friend_get_vcard(lf)); BC_ASSERT_STRING_EQUAL(linphone_vcard_get_full_name(linphone_friend_get_vcard(lf)), "Old Friend"); + linphone_friend_unref(lf); + lf = NULL; } static void friends_if_no_db_set(void) {