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);