Commit 0b7a1dec authored by Sylvain Berfini's avatar Sylvain Berfini 🎩
Browse files

Added friend storage to database + improved tests + needed changes in gtk app...

Added friend storage to database + improved tests + needed changes in gtk app + friends' migration from rc to db
parent 8ac8e127
...@@ -351,9 +351,13 @@ const LinphoneAddress *linphone_friend_get_address(const LinphoneFriend *lf){ ...@@ -351,9 +351,13 @@ const LinphoneAddress *linphone_friend_get_address(const LinphoneFriend *lf){
} }
const char * linphone_friend_get_name(const LinphoneFriend *lf) { const char * linphone_friend_get_name(const LinphoneFriend *lf) {
LinphoneAddress *fr = lf->uri; if (lf && lf->vcard) {
if (fr == NULL) return NULL; return linphone_vcard_get_full_name(lf->vcard);
return linphone_address_get_display_name(fr); } 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){ bool_t linphone_friend_get_send_subscribe(const LinphoneFriend *lf){
...@@ -519,15 +523,15 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc) { ...@@ -519,15 +523,15 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc) {
if (fr->lc) { if (fr->lc) {
linphone_friend_update_subscribes(fr, NULL, linphone_core_should_subscribe_friends_only_when_registered(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; lc->bl_refresh = TRUE;
fr->commit = FALSE; 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); ms_return_if_fail(fr);
if (!fr->lc) return; if (!fr->lc) return;
linphone_friend_apply(fr, fr->lc); linphone_friend_apply(fr, fr->lc);
...@@ -542,8 +546,7 @@ LinphoneFriend * linphone_core_create_friend_with_address(LinphoneCore *lc, cons ...@@ -542,8 +546,7 @@ LinphoneFriend * linphone_core_create_friend_with_address(LinphoneCore *lc, cons
return linphone_friend_new_with_address(address); return linphone_friend_new_with_address(address);
} }
void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) { void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) {
ms_return_if_fail(!lf->lc);
if (!lf->uri) { if (!lf->uri) {
return; // Do not abort if friend doesn't have a SIP 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) { ...@@ -578,13 +581,13 @@ void linphone_core_import_friend(LinphoneCore *lc, LinphoneFriend *lf) {
void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* lf){ void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* lf){
MSList *el = ms_list_find(lc->friends, lf); MSList *el = ms_list_find(lc->friends, lf);
if (el != NULL) { 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 #ifdef FRIENDS_SQL_STORAGE_ENABLED
linphone_core_remove_friend_from_db(lc, lf); linphone_core_remove_friend_from_db(lc, lf);
#else #else
linphone_core_write_friends_config(lc); linphone_core_write_friends_config(lc);
#endif #endif
linphone_friend_unref(lf);
} else { } else {
ms_error("linphone_core_remove_friend(): friend [%p] is not part of core's list.", lf); 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) { ...@@ -940,8 +943,13 @@ static void linphone_create_table(sqlite3* db) {
char* errmsg = NULL; char* errmsg = NULL;
int ret; int ret;
ret = sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS friends (" ret = sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS friends ("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
");",//TODO "sip_uri TEXT NOT NULL,"
"subscribe_policy INTEGER,"
"send_subscribe INTEGER,"
"ref_key TEXT,"
"vCard TEXT"
");",
0, 0, &errmsg); 0, 0, &errmsg);
if (ret != SQLITE_OK) { if (ret != SQLITE_OK) {
ms_error("Error in creation: %s.\n", errmsg); ms_error("Error in creation: %s.\n", errmsg);
...@@ -957,6 +965,7 @@ void linphone_core_friends_storage_init(LinphoneCore *lc) { ...@@ -957,6 +965,7 @@ void linphone_core_friends_storage_init(LinphoneCore *lc) {
int ret; int ret;
const char *errmsg; const char *errmsg;
sqlite3 *db; sqlite3 *db;
const MSList *friends = NULL;
linphone_core_friends_storage_close(lc); linphone_core_friends_storage_close(lc);
...@@ -971,6 +980,15 @@ void linphone_core_friends_storage_init(LinphoneCore *lc) { ...@@ -971,6 +980,15 @@ void linphone_core_friends_storage_init(LinphoneCore *lc) {
linphone_create_table(db); linphone_create_table(db);
linphone_update_table(db); linphone_update_table(db);
lc->friends_db = 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) { void linphone_core_friends_storage_close(LinphoneCore *lc) {
...@@ -982,6 +1000,11 @@ void linphone_core_friends_storage_close(LinphoneCore *lc) { ...@@ -982,6 +1000,11 @@ void linphone_core_friends_storage_close(LinphoneCore *lc) {
/* DB layout: /* DB layout:
* | 0 | storage_id * | 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) { static int create_friend(void *data, int argc, char **argv, char **colName) {
MSList **list = (MSList **)data; MSList **list = (MSList **)data;
...@@ -989,16 +1012,18 @@ static int create_friend(void *data, int argc, char **argv, char **colName) { ...@@ -989,16 +1012,18 @@ static int create_friend(void *data, int argc, char **argv, char **colName) {
LinphoneVCard *vcard = NULL; LinphoneVCard *vcard = NULL;
unsigned int storage_id = atoi(argv[0]); 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); lf = linphone_friend_new_from_vcard(vcard);
if (!lf) { if (!lf) {
LinphoneAddress *addr = linphone_address_new(argv[1]);
lf = linphone_friend_new(); lf = linphone_friend_new();
//TODO linphone_friend_set_address(lf, addr);
} }
linphone_friend_set_inc_subscribe_policy(lf, atoi(argv[2]));
//TODO linphone_friend_send_subscribe(lf, atoi(argv[3]));
linphone_friend_set_ref_key(lf, argv[4]);
lf->storage_id = storage_id; lf->storage_id = storage_id;
*list = ms_list_append(*list, linphone_friend_ref(lf)); *list = ms_list_append(*list, linphone_friend_ref(lf));
linphone_friend_unref(lf); linphone_friend_unref(lf);
return 0; return 0;
...@@ -1031,11 +1056,22 @@ void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) { ...@@ -1031,11 +1056,22 @@ void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) {
char *buf; char *buf;
if (lf->storage_id > 0) { 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 lf->storage_id
); );
} else { } 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); linphone_sql_request_generic(lc->friends_db, buf);
sqlite3_free(buf); sqlite3_free(buf);
...@@ -1047,12 +1083,14 @@ void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) { ...@@ -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) { 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; 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);", buf = sqlite3_mprintf("DELETE FROM friends WHERE id = %i", lf->storage_id);
lf->storage_id
);
linphone_sql_request_generic(lc->friends_db, buf); linphone_sql_request_generic(lc->friends_db, buf);
sqlite3_free(buf); sqlite3_free(buf);
...@@ -1065,7 +1103,10 @@ MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) { ...@@ -1065,7 +1103,10 @@ MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc) {
uint64_t begin,end; uint64_t begin,end;
MSList *result = NULL; 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"); 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) ...@@ -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) { void linphone_core_migrate_friends_from_rc_to_db(LinphoneCore *lc) {
LpConfig *lpc = NULL;
LinphoneFriend *lf = NULL;
int i;
#ifndef FRIENDS_SQL_STORAGE_ENABLED #ifndef FRIENDS_SQL_STORAGE_ENABLED
ms_warning("linphone has been compiled without sqlite, can't migrate friends"); ms_warning("linphone has been compiled without sqlite, can't migrate friends");
return; return;
#endif #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
...@@ -1364,19 +1364,14 @@ static void video_config_read(LinphoneCore *lc){ ...@@ -1364,19 +1364,14 @@ static void video_config_read(LinphoneCore *lc){
static void ui_config_read(LinphoneCore *lc) static void ui_config_read(LinphoneCore *lc)
{ {
#ifndef FRIENDS_SQL_STORAGE_ENABLED
LinphoneFriend *lf = NULL; 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; int i;
for (i=0;(lf=linphone_friend_new_from_config_file(lc,i))!=NULL;i++){ for (i = 0; (lf = linphone_friend_new_from_config_file(lc, i)) != NULL; i++) {
#endif
linphone_core_add_friend(lc, lf); linphone_core_add_friend(lc, lf);
linphone_friend_unref(lf); linphone_friend_unref(lf);
} }
#endif
call_logs_read_from_config_file(lc); call_logs_read_from_config_file(lc);
} }
......
...@@ -687,14 +687,14 @@ void linphone_gtk_show_friends(void){ ...@@ -687,14 +687,14 @@ void linphone_gtk_show_friends(void){
LinphoneFriend *lf=(LinphoneFriend*)itf->data; LinphoneFriend *lf=(LinphoneFriend*)itf->data;
const LinphoneAddress *f_uri=linphone_friend_get_address(lf); const LinphoneAddress *f_uri=linphone_friend_get_address(lf);
char *uri=linphone_address_as_string(f_uri); 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; const char *display=name;
char *escaped=NULL; char *escaped=NULL;
int nbmsg=0; int nbmsg=0;
//BuddyInfo *bi; //BuddyInfo *bi;
gboolean send_subscribe=linphone_friend_get_send_subscribe(lf); 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); display=linphone_address_get_username(f_uri);
} }
gtk_list_store_append(store,&iter); gtk_list_store_append(store,&iter);
......
...@@ -2223,6 +2223,9 @@ core_start: ...@@ -2223,6 +2223,9 @@ core_start:
#ifdef CALL_LOGS_STORAGE_ENABLED #ifdef CALL_LOGS_STORAGE_ENABLED
linphone_gtk_call_log_update(the_ui); linphone_gtk_call_log_update(the_ui);
#endif #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...*/ /* 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()); gtk_timeout_add(30,(GtkFunction)linphone_gtk_iterate,(gpointer)linphone_gtk_get_core());
......
...@@ -68,7 +68,8 @@ RCFILES = \ ...@@ -68,7 +68,8 @@ RCFILES = \
rcfiles/remote_zero_length_params_rc\ rcfiles/remote_zero_length_params_rc\
rcfiles/stun_rc\ rcfiles/stun_rc\
rcfiles/upnp_rc\ rcfiles/upnp_rc\
rcfiles/zero_length_params_rc rcfiles/zero_length_params_rc\
rcfiles/friends_rc
IMAGE_FILES = images/nowebcamCIF.jpg IMAGE_FILES = images/nowebcamCIF.jpg
......
[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" <sip:francois.grisez@sip.linphone.org>
pol=accept
subscribe=1
[friend_2]
url=sip:margaux.clerc@sip.linphone.org
pol=deny
subscribe=0
...@@ -42,7 +42,7 @@ static void linphone_vcard_import_export_friends_test(void) { ...@@ -42,7 +42,7 @@ static void linphone_vcard_import_export_friends_test(void) {
linphone_core_export_friends_as_vcard4_file(manager->lc, export_filepath); 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); friends = linphone_core_get_friend_list(manager->lc);
BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d");
...@@ -96,30 +96,24 @@ static void friends_if_no_db_set(void) { ...@@ -96,30 +96,24 @@ static void friends_if_no_db_set(void) {
#ifdef FRIENDS_SQL_STORAGE_ENABLED #ifdef FRIENDS_SQL_STORAGE_ENABLED
static void friends_migration(void) { static void friends_migration(void) {
LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); LinphoneCoreManager* manager = linphone_core_manager_new2("friends_rc", FALSE);
LinphoneFriend *lf = linphone_friend_new();
LinphoneFriend *lf2 = NULL;
LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org");
const MSList *friends = linphone_core_get_friend_list(manager->lc); const MSList *friends = linphone_core_get_friend_list(manager->lc);
MSList *friends_from_db = NULL; MSList *friends_from_db = NULL;
char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db");
BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); 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); unlink(friends_db);
linphone_core_set_friends_database_path(manager->lc, 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);
BC_ASSERT_EQUAL_FATAL(ms_list_size(friends_from_db), 1, int, "%d"); BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 3, int, "%d");
if (ms_list_size(friends_from_db) < 3) {
lf2 = (LinphoneFriend *)friends_from_db->data; goto end;
BC_ASSERT_EQUAL(linphone_friend_get_name(lf2), linphone_friend_get_name(lf), const char *, "%s"); }
friends = linphone_core_get_friend_list(manager->lc);
BC_ASSERT_EQUAL(ms_list_size(friends), 3, int, "%d");
end:
unlink(friends_db); unlink(friends_db);
ms_free(friends_db); ms_free(friends_db);
linphone_address_destroy(addr); linphone_address_destroy(addr);
...@@ -146,15 +140,41 @@ static void friends_sqlite_storage(void) { ...@@ -146,15 +140,41 @@ static void friends_sqlite_storage(void) {
linphone_friend_set_name(lf, "Sylvain"); linphone_friend_set_name(lf, "Sylvain");
linphone_core_add_friend(manager->lc, lf); linphone_core_add_friend(manager->lc, lf);
linphone_friend_unref(lf); linphone_friend_unref(lf);
BC_ASSERT_EQUAL(lf->storage_id, 1, int, "%d");
friends = linphone_core_get_friend_list(manager->lc); 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), 1, int, "%d");
friends_from_db = linphone_core_fetch_friends_from_db(manager->lc); friends_from_db = linphone_core_fetch_friends_from_db(manager->lc);
BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d"); 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), 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; 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), "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); unlink(friends_db);
ms_free(friends_db); ms_free(friends_db);
linphone_address_destroy(addr); linphone_address_destroy(addr);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment