mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-02 19:29:27 +00:00
Store call logs in sql database + new method to get all call logs related to a linphone address
This commit is contained in:
parent
4dd7ab621d
commit
cabf15f1f5
10 changed files with 457 additions and 17 deletions
38
configure.ac
38
configure.ac
|
|
@ -894,7 +894,7 @@ if test x$enable_msg_storage != xfalse; then
|
|||
AC_CHECK_LIB(sqlite3, sqlite3_open, [SQLITE3_LIBS+=" -lsqlite3 "; found_sqlite=yes], [foo=bar])
|
||||
fi
|
||||
if test "$found_sqlite" = "yes"; then
|
||||
SQLITE3_CFLAGS+="-DMSG_STORAGE_ENABLED"
|
||||
SQLITE3_CFLAGS+=" -DMSG_STORAGE_ENABLED"
|
||||
if test "$build_macos" = "yes" -o "$ios_found" = "yes"; then
|
||||
SQLITE3_LIBS+=" -liconv"
|
||||
fi
|
||||
|
|
@ -912,6 +912,41 @@ fi
|
|||
|
||||
AM_CONDITIONAL(BUILD_MSG_STORAGE, test x$enable_msg_storage = xtrue)
|
||||
|
||||
AC_ARG_ENABLE(call-logs-storage,
|
||||
[AS_HELP_STRING([--enable-call-logs-storage=[yes/no]], [Turn on compilation of call logs storage (default=auto)])],
|
||||
[case "${enableval}" in
|
||||
yes) enable_call_logs_storage=true ;;
|
||||
no) enable_call_logs_storage=false ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-call-logs-storage) ;;
|
||||
esac],
|
||||
[enable_call_logs_storage=auto]
|
||||
)
|
||||
|
||||
if test x$enable_call_logs_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+=" -DCALL_LOGS_STORAGE_ENABLED"
|
||||
if test "$build_macos" = "yes" -o "$ios_found" = "yes"; then
|
||||
SQLITE3_LIBS+=" -liconv"
|
||||
fi
|
||||
enable_call_logs_storage=true
|
||||
else
|
||||
if test x$enable_call_logs_storage = xtrue; then
|
||||
AC_MSG_ERROR([sqlite3, required for call logs storage, not found])
|
||||
fi
|
||||
enable_call_logs_storage=false
|
||||
fi
|
||||
|
||||
AC_SUBST(SQLITE3_CFLAGS)
|
||||
AC_SUBST(SQLITE3_LIBS)
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(BUILD_CALL_LOGS_STORAGE, test x$enable_call_logs_storage = xtrue)
|
||||
|
||||
PKG_CHECK_MODULES(BELLESIP, [belle-sip >= 1.4.0])
|
||||
|
||||
SIPSTACK_CFLAGS="$BELLESIP_CFLAGS"
|
||||
|
|
@ -1065,6 +1100,7 @@ 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" "IM encryption" $lime
|
||||
printf "* %-30s %s\n" "uPnP support" $build_upnp
|
||||
printf "* %-30s %s\n" "LDAP support" $enable_ldap
|
||||
|
|
|
|||
|
|
@ -22,6 +22,20 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include <time.h>
|
||||
#include "private.h"
|
||||
|
||||
#ifdef CALL_LOGS_STORAGE_ENABLED
|
||||
#ifndef _WIN32
|
||||
#if !defined(ANDROID) && !defined(__QNXNTO__)
|
||||
# include <langinfo.h>
|
||||
# include <iconv.h>
|
||||
# include <string.h>
|
||||
#endif
|
||||
#else
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#define MAX_PATH_SIZE 1024
|
||||
#include "sqlite3.h"
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Internal functions *
|
||||
|
|
@ -278,6 +292,7 @@ LinphoneCallLog * linphone_call_log_new(LinphoneCallDir dir, LinphoneAddress *fr
|
|||
cl->to=to;
|
||||
cl->status=LinphoneCallAborted; /*default status*/
|
||||
cl->quality=-1;
|
||||
cl->storage_id=0;
|
||||
|
||||
cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]=linphone_reporting_new();
|
||||
cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]=linphone_reporting_new();
|
||||
|
|
@ -298,3 +313,301 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneCallLog, belle_sip_object_t,
|
|||
NULL, // marshal
|
||||
FALSE
|
||||
);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* SQL storage related functions *
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef CALL_LOGS_STORAGE_ENABLED
|
||||
|
||||
static void linphone_create_table(sqlite3* db){
|
||||
char* errmsg=NULL;
|
||||
int ret;
|
||||
ret=sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS call_history ("
|
||||
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
||||
"caller TEXT NOT NULL," // Can't name a field "from"...
|
||||
"callee TEXT NOT NULL,"
|
||||
"direction INTEGER,"
|
||||
"duration INTEGER,"
|
||||
"start_time TEXT NOT NULL,"
|
||||
"connected_time TEXT NOT NULL,"
|
||||
"status INTEGER,"
|
||||
"videoEnabled INTEGER,"
|
||||
"quality REAL"
|
||||
");",
|
||||
0,0,&errmsg);
|
||||
if(ret != SQLITE_OK) {
|
||||
ms_error("Error in creation: %s.\n", errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
static int _linphone_sqlite3_open(const char *db_file, sqlite3 **db) {
|
||||
#if defined(ANDROID) || defined(__QNXNTO__)
|
||||
return sqlite3_open(db_file, db);
|
||||
#elif defined(_WIN32)
|
||||
int ret;
|
||||
wchar_t db_file_utf16[MAX_PATH_SIZE];
|
||||
ret = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, db_file, -1, db_file_utf16, MAX_PATH_SIZE);
|
||||
if(ret == 0) db_file_utf16[0] = '\0';
|
||||
return sqlite3_open16(db_file_utf16, db);
|
||||
#else
|
||||
char db_file_locale[MAX_PATH_SIZE] = {'\0'};
|
||||
char db_file_utf8[MAX_PATH_SIZE] = "";
|
||||
char *inbuf=db_file_locale, *outbuf=db_file_utf8;
|
||||
size_t inbyteleft = MAX_PATH_SIZE, outbyteleft = MAX_PATH_SIZE;
|
||||
iconv_t cb;
|
||||
|
||||
strncpy(db_file_locale, db_file, MAX_PATH_SIZE-1);
|
||||
cb = iconv_open("UTF-8", nl_langinfo(CODESET));
|
||||
if(cb != (iconv_t)-1) {
|
||||
int ret;
|
||||
ret = iconv(cb, &inbuf, &inbyteleft, &outbuf, &outbyteleft);
|
||||
if(ret == -1) db_file_utf8[0] = '\0';
|
||||
iconv_close(cb);
|
||||
}
|
||||
return sqlite3_open(db_file_utf8, db);
|
||||
#endif
|
||||
}
|
||||
|
||||
void linphone_core_call_log_storage_init(LinphoneCore *lc) {
|
||||
int ret;
|
||||
const char *errmsg;
|
||||
sqlite3 *db;
|
||||
|
||||
linphone_core_message_storage_close(lc);
|
||||
|
||||
ret=_linphone_sqlite3_open(lc->logs_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);
|
||||
lc->logs_db = db;
|
||||
|
||||
// Load the existing call logs
|
||||
linphone_call_log_get_history(lc);
|
||||
}
|
||||
|
||||
void linphone_core_call_log_storage_close(LinphoneCore *lc) {
|
||||
if (lc->logs_db){
|
||||
sqlite3_close(lc->logs_db);
|
||||
lc->logs_db = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* DB layout:
|
||||
* | 0 | storage_id
|
||||
* | 1 | from
|
||||
* | 2 | to
|
||||
* | 3 | direction flag
|
||||
* | 4 | duration
|
||||
* | 5 | start date time (time_t)
|
||||
* | 6 | connected date time (time_t)
|
||||
* | 7 | status
|
||||
* | 8 | video enabled (1 or 0)
|
||||
* | 9 | quality
|
||||
*/
|
||||
static int create_call_log(void *data, int argc, char **argv, char **colName) {
|
||||
LinphoneCore *lc = (LinphoneCore *)data;
|
||||
LinphoneAddress *from;
|
||||
LinphoneAddress *to;
|
||||
LinphoneCallDir dir;
|
||||
LinphoneCallLog *log;
|
||||
|
||||
unsigned int storage_id = atoi(argv[0]);
|
||||
from = linphone_address_new(argv[1]);
|
||||
to = linphone_address_new(argv[2]);
|
||||
dir = (LinphoneCallDir) atoi(argv[3]);
|
||||
log = linphone_call_log_new(dir, from, to);
|
||||
|
||||
log->storage_id = storage_id;
|
||||
log->duration = atoi(argv[4]);
|
||||
log->start_date_time = (time_t)atol(argv[5]);
|
||||
log->connected_date_time = (time_t)atol(argv[6]);
|
||||
log->status = (LinphoneCallStatus) atoi(argv[7]);
|
||||
log->video_enabled = atoi(argv[8]) == 1;
|
||||
log->quality = atof(argv[9]);
|
||||
|
||||
lc->call_logs = ms_list_prepend(lc->call_logs, linphone_call_log_ref(log));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void linphone_sql_request_call_log(sqlite3 *db, const char *stmt, LinphoneCore *lc){
|
||||
char* errmsg = NULL;
|
||||
int ret;
|
||||
ret = sqlite3_exec(db, stmt, create_call_log, lc, &errmsg);
|
||||
if (ret != SQLITE_OK) {
|
||||
ms_error("Error in creation: %s.", errmsg);
|
||||
sqlite3_free(errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
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_call_log_store(LinphoneCore *lc, LinphoneCallLog *log) {
|
||||
if (lc && lc->logs_db){
|
||||
char *from, *to;
|
||||
char *buf;
|
||||
|
||||
from = linphone_address_as_string(log->from);
|
||||
to = linphone_address_as_string(log->to);
|
||||
buf = sqlite3_mprintf("INSERT INTO call_history VALUES(NULL,%Q,%Q,%i,%i,%lld,%lld,%i,%i,%f);",
|
||||
from,
|
||||
to,
|
||||
log->dir,
|
||||
log->duration,
|
||||
(int64_t)log->start_date_time,
|
||||
(int64_t)log->connected_date_time,
|
||||
log->status,
|
||||
log->video_enabled ? 1 : 0,
|
||||
log->quality
|
||||
);
|
||||
linphone_sql_request_generic(lc->logs_db, buf);
|
||||
sqlite3_free(buf);
|
||||
ms_free(from);
|
||||
ms_free(to);
|
||||
sqlite3_last_insert_rowid(lc->logs_db);
|
||||
}
|
||||
|
||||
if (lc) {
|
||||
lc->call_logs = ms_list_prepend(lc->call_logs, linphone_call_log_ref(log));
|
||||
}
|
||||
}
|
||||
|
||||
MSList *linphone_call_log_get_history(LinphoneCore *lc) {
|
||||
char *buf;
|
||||
uint64_t begin,end;
|
||||
|
||||
if (!lc || lc->logs_db == NULL) return NULL;
|
||||
|
||||
ms_list_for_each(lc->call_logs, (void (*)(void*))linphone_call_log_unref);
|
||||
lc->call_logs = ms_list_free(lc->call_logs);
|
||||
|
||||
buf = sqlite3_mprintf("SELECT * FROM call_history ORDER BY id ASC LIMIT %i", lc->max_call_logs);
|
||||
|
||||
begin = ortp_get_cur_time_ms();
|
||||
linphone_sql_request_call_log(lc->logs_db, buf, lc);
|
||||
end = ortp_get_cur_time_ms();
|
||||
ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin));
|
||||
sqlite3_free(buf);
|
||||
|
||||
return lc->call_logs;
|
||||
}
|
||||
|
||||
void linphone_call_log_delete_history(LinphoneCore *lc) {
|
||||
char *buf;
|
||||
|
||||
if (!lc || lc->logs_db == NULL) return ;
|
||||
|
||||
buf = sqlite3_mprintf("DELETE FROM call_history");
|
||||
linphone_sql_request_generic(lc->logs_db, buf);
|
||||
sqlite3_free(buf);
|
||||
}
|
||||
|
||||
void linphone_call_log_delete_log(LinphoneCore *lc, LinphoneCallLog *log) {
|
||||
char *buf;
|
||||
|
||||
if (!lc || lc->logs_db == NULL) return ;
|
||||
|
||||
buf = sqlite3_mprintf("DELETE FROM call_history WHERE id = %i", log->storage_id);
|
||||
linphone_sql_request_generic(lc->logs_db, buf);
|
||||
sqlite3_free(buf);
|
||||
|
||||
lc->call_logs = ms_list_remove(lc->call_logs, log);
|
||||
linphone_call_log_unref(log);
|
||||
}
|
||||
|
||||
int linphone_call_log_get_history_size(LinphoneCore *lc) {
|
||||
int numrows = 0;
|
||||
char *buf;
|
||||
sqlite3_stmt *selectStatement;
|
||||
int returnValue;
|
||||
|
||||
if (!lc || lc->logs_db == NULL) return 0;
|
||||
|
||||
buf = sqlite3_mprintf("SELECT count(*) FROM call_history");
|
||||
returnValue = sqlite3_prepare_v2(lc->logs_db, buf, -1, &selectStatement, NULL);
|
||||
if (returnValue == SQLITE_OK){
|
||||
if(sqlite3_step(selectStatement) == SQLITE_ROW){
|
||||
numrows = sqlite3_column_int(selectStatement, 0);
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(selectStatement);
|
||||
sqlite3_free(buf);
|
||||
|
||||
return numrows;
|
||||
}
|
||||
|
||||
const MSList * linphone_core_get_call_logs_for_address(LinphoneCore *lc, LinphoneAddress *addr) {
|
||||
char *buf;
|
||||
char *sipAddress;
|
||||
uint64_t begin,end;
|
||||
MSList *result, *tmp;
|
||||
|
||||
if (!lc || lc->logs_db == NULL || addr == NULL) return NULL;
|
||||
|
||||
tmp = lc->call_logs;
|
||||
lc->call_logs = NULL;
|
||||
|
||||
/*since we want to append query parameters depending on arguments given, we use malloc instead of sqlite3_mprintf*/
|
||||
sipAddress = linphone_address_as_string_uri_only(addr);
|
||||
buf = sqlite3_mprintf("SELECT * FROM call_history WHERE caller LIKE '%%%q%%' OR callee LIKE '%%%q%%' ORDER BY id ASC", sipAddress, sipAddress); // The '%%%q%%' takes care of the eventual presence of a display name
|
||||
|
||||
begin = ortp_get_cur_time_ms();
|
||||
linphone_sql_request_call_log(lc->logs_db, buf, lc);
|
||||
end = ortp_get_cur_time_ms();
|
||||
ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin));
|
||||
sqlite3_free(buf);
|
||||
ms_free(sipAddress);
|
||||
|
||||
result = lc->call_logs;
|
||||
lc->call_logs = tmp;
|
||||
tmp = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void linphone_core_call_log_storage_init(LinphoneCore *lc) {
|
||||
}
|
||||
|
||||
void linphone_core_call_log_storage_close(LinphoneCore *lc) {
|
||||
}
|
||||
|
||||
void linphone_call_log_store(LinphoneCore *lc, LinphoneCallLog *log) {
|
||||
}
|
||||
|
||||
MSList *linphone_call_log_get_history(LinphoneCore *lc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_call_log_delete_history(LinphoneCore *lc) {
|
||||
}
|
||||
|
||||
void linphone_call_log_delete_log(LinphoneCore *lc, LinphoneCallLog *log) {
|
||||
}
|
||||
|
||||
int linphone_call_log_get_history_size(LinphoneCore *lc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const MSList * linphone_core_get_call_logs_for_address(LinphoneCore *lc, LinphoneAddress *addr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -3945,6 +3945,9 @@ void linphone_call_log_completed(LinphoneCall *call){
|
|||
linphone_core_notify_display_status(lc,info);
|
||||
ms_free(info);
|
||||
}
|
||||
#ifdef CALL_LOGS_STORAGE_ENABLED
|
||||
linphone_call_log_store(lc, call->log);
|
||||
#else
|
||||
lc->call_logs=ms_list_prepend(lc->call_logs,linphone_call_log_ref(call->log));
|
||||
if (ms_list_size(lc->call_logs)>lc->max_call_logs){
|
||||
MSList *elem,*prevelem=NULL;
|
||||
|
|
@ -3956,8 +3959,9 @@ void linphone_call_log_completed(LinphoneCall *call){
|
|||
linphone_call_log_unref((LinphoneCallLog*)elem->data);
|
||||
lc->call_logs=ms_list_remove_link(lc->call_logs,elem);
|
||||
}
|
||||
linphone_core_notify_call_log_updated(lc,call->log);
|
||||
call_logs_write_to_config_file(lc);
|
||||
#endif
|
||||
linphone_core_notify_call_log_updated(lc,call->log);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1294,7 +1294,10 @@ static void ui_config_read(LinphoneCore *lc)
|
|||
linphone_core_add_friend(lc,lf);
|
||||
linphone_friend_unref(lf);
|
||||
}
|
||||
|
||||
#ifndef CALL_LOGS_STORAGE_ENABLED
|
||||
call_logs_read_from_config_file(lc);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -4929,15 +4932,33 @@ LinphoneFirewallPolicy linphone_core_get_firewall_policy(const LinphoneCore *lc)
|
|||
* Call log related functions *
|
||||
******************************************************************************/
|
||||
|
||||
const MSList * linphone_core_get_call_logs(LinphoneCore *lc){
|
||||
void linphone_core_set_call_logs_database_path(LinphoneCore *lc, const char *path){
|
||||
if (lc->logs_db_file){
|
||||
ms_free(lc->logs_db_file);
|
||||
lc->logs_db_file = NULL;
|
||||
}
|
||||
if (path) {
|
||||
lc->logs_db_file = ms_strdup(path);
|
||||
linphone_core_call_log_storage_init(lc);
|
||||
}
|
||||
}
|
||||
|
||||
const MSList* linphone_core_get_call_logs(LinphoneCore *lc) {
|
||||
#ifdef CALL_LOGS_STORAGE_ENABLED
|
||||
linphone_call_log_get_history(lc);
|
||||
#endif
|
||||
return lc->call_logs;
|
||||
}
|
||||
|
||||
void linphone_core_clear_call_logs(LinphoneCore *lc){
|
||||
void linphone_core_clear_call_logs(LinphoneCore *lc) {
|
||||
lc->missed_calls=0;
|
||||
ms_list_for_each(lc->call_logs,(void (*)(void*))linphone_call_log_unref);
|
||||
lc->call_logs=ms_list_free(lc->call_logs);
|
||||
#ifdef CALL_LOGS_STORAGE_ENABLED
|
||||
linphone_call_log_delete_history(lc);
|
||||
#else
|
||||
ms_list_for_each(lc->call_logs, (void (*)(void*))linphone_call_log_unref);
|
||||
lc->call_logs = ms_list_free(lc->call_logs);
|
||||
call_logs_write_to_config_file(lc);
|
||||
#endif
|
||||
}
|
||||
|
||||
int linphone_core_get_missed_calls_count(LinphoneCore *lc) {
|
||||
|
|
@ -4949,12 +4970,19 @@ void linphone_core_reset_missed_calls_count(LinphoneCore *lc) {
|
|||
}
|
||||
|
||||
void linphone_core_remove_call_log(LinphoneCore *lc, LinphoneCallLog *cl){
|
||||
#ifdef CALL_LOGS_STORAGE_ENABLED
|
||||
linphone_call_log_delete_log(lc, cl);
|
||||
#else
|
||||
lc->call_logs = ms_list_remove(lc->call_logs, cl);
|
||||
call_logs_write_to_config_file(lc);
|
||||
linphone_call_log_unref(cl);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Video related functions *
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
static void toggle_video_preview(LinphoneCore *lc, bool_t val){
|
||||
|
|
@ -6170,6 +6198,7 @@ static void linphone_core_uninit(LinphoneCore *lc)
|
|||
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);
|
||||
ms_exit();
|
||||
linphone_core_set_state(lc,LinphoneGlobalOff,"Off");
|
||||
linphone_core_deactivate_log_serialization_if_needed();
|
||||
|
|
|
|||
|
|
@ -3170,6 +3170,14 @@ LINPHONE_PUBLIC void linphone_core_set_rtp_no_xmit_on_audio_mute(LinphoneCore *l
|
|||
**/
|
||||
LINPHONE_PUBLIC const MSList * linphone_core_get_call_logs(LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Get the list of call logs (past calls) that matches the given #LinphoneAddress.
|
||||
* At the contrary of linphone_core_get_call_logs, it is your responsability to unref the logs and free this list once you are done using it.
|
||||
* @param[in] lc LinphoneCore object
|
||||
* @return \mslist{LinphoneCallLog}
|
||||
**/
|
||||
LINPHONE_PUBLIC const MSList * linphone_core_get_call_logs_for_address(LinphoneCore *lc, LinphoneAddress *addr);
|
||||
|
||||
/**
|
||||
* Erase the call log.
|
||||
* @param[in] lc LinphoneCore object
|
||||
|
|
@ -3198,6 +3206,15 @@ LINPHONE_PUBLIC void linphone_core_reset_missed_calls_count(LinphoneCore *lc);
|
|||
**/
|
||||
LINPHONE_PUBLIC void linphone_core_remove_call_log(LinphoneCore *lc, LinphoneCallLog *call_log);
|
||||
|
||||
/**
|
||||
* Sets the database filename where call logs 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_call_logs_database_path(LinphoneCore *lc, const char *path);
|
||||
|
||||
/**
|
||||
* @}
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -433,11 +433,6 @@ MSList *linphone_chat_room_get_history(LinphoneChatRoom *cr,int nb_message){
|
|||
return linphone_chat_room_get_history_range(cr, 0, nb_message-1);
|
||||
}
|
||||
|
||||
|
||||
void linphone_close_storage(sqlite3* db){
|
||||
sqlite3_close(db);
|
||||
}
|
||||
|
||||
void linphone_create_table(sqlite3* db){
|
||||
char* errmsg=NULL;
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ struct _LinphoneCallLog{
|
|||
char* call_id; /**unique id of a call*/
|
||||
struct _LinphoneQualityReporting reporting;
|
||||
bool_t video_enabled;
|
||||
unsigned int storage_id;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneCallLog);
|
||||
|
|
@ -846,6 +847,10 @@ struct _LinphoneCore
|
|||
#ifdef MSG_STORAGE_ENABLED
|
||||
sqlite3 *db;
|
||||
bool_t debug_storage;
|
||||
#endif
|
||||
char *logs_db_file;
|
||||
#ifdef CALL_LOGS_STORAGE_ENABLED
|
||||
sqlite3 *logs_db;
|
||||
#endif
|
||||
#ifdef BUILD_UPNP
|
||||
UpnpContext *upnp;
|
||||
|
|
@ -962,6 +967,13 @@ void _linphone_core_codec_config_write(LinphoneCore *lc);
|
|||
#endif
|
||||
void call_logs_read_from_config_file(LinphoneCore *lc);
|
||||
void call_logs_write_to_config_file(LinphoneCore *lc);
|
||||
void linphone_core_call_log_storage_init(LinphoneCore *lc);
|
||||
void linphone_core_call_log_storage_close(LinphoneCore *lc);
|
||||
void linphone_call_log_store(LinphoneCore *lc, LinphoneCallLog *log);
|
||||
MSList *linphone_call_log_get_history(LinphoneCore *lc);
|
||||
void linphone_call_log_delete_history(LinphoneCore *lc);
|
||||
void linphone_call_log_delete_log(LinphoneCore *lc, LinphoneCallLog *log);
|
||||
int linphone_call_log_get_history_size(LinphoneCore *lc);
|
||||
|
||||
int linphone_core_get_edge_bw(LinphoneCore *lc);
|
||||
int linphone_core_get_edge_ptime(LinphoneCore *lc);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,34 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "linphone.h"
|
||||
|
||||
#define CONFIG_FILE ".linphone-call-history.db"
|
||||
|
||||
char *linphone_gtk_call_logs_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;
|
||||
}
|
||||
|
||||
static void fill_renderers(GtkTreeView *v){
|
||||
GtkTreeViewColumn *c;
|
||||
GtkCellRenderer *r;
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ LINPHONE_PUBLIC GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char
|
|||
LINPHONE_PUBLIC GtkWidget *linphone_gtk_create_widget(const char* widget_name);
|
||||
|
||||
char *linphone_gtk_message_storage_get_db_file(const char *filename);
|
||||
char *linphone_gtk_call_logs_storage_get_db_file(const char *filename);
|
||||
LINPHONE_PUBLIC void linphone_gtk_show_assistant(GtkWidget* parent);
|
||||
LINPHONE_PUBLIC void linphone_gtk_close_assistant(void);
|
||||
|
||||
|
|
|
|||
17
gtk/main.c
17
gtk/main.c
|
|
@ -259,7 +259,7 @@ 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 *db_file) {
|
||||
const char *factory_config_file, const char *chat_messages_db_file, const char *call_logs_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);
|
||||
|
|
@ -309,7 +309,8 @@ static void linphone_gtk_init_liblinphone(const char *config_file,
|
|||
_linphone_gtk_enable_video(FALSE);
|
||||
linphone_gtk_set_ui_config_int("videoselfview",0);
|
||||
}
|
||||
if (db_file) linphone_core_set_chat_database_path(the_core,db_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);
|
||||
}
|
||||
|
||||
LinphoneCore *linphone_gtk_get_core(void){
|
||||
|
|
@ -2063,7 +2064,7 @@ int main(int argc, char *argv[]){
|
|||
GdkPixbuf *pbuf;
|
||||
const char *app_name="Linphone";
|
||||
LpConfig *factory;
|
||||
char *db_file;
|
||||
char *chat_messages_db_file, *call_logs_db_file;
|
||||
GError *error=NULL;
|
||||
const char *tmp;
|
||||
|
||||
|
|
@ -2213,9 +2214,13 @@ core_start:
|
|||
linphone_gtk_create_log_window();
|
||||
linphone_core_enable_logs_with_cb(linphone_gtk_log_handler);
|
||||
|
||||
db_file=linphone_gtk_message_storage_get_db_file(NULL);
|
||||
linphone_gtk_init_liblinphone(config_file, factory_config_file, db_file);
|
||||
g_free(db_file);
|
||||
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);
|
||||
g_free(chat_messages_db_file);
|
||||
g_free(call_logs_db_file);
|
||||
|
||||
linphone_gtk_call_log_update(the_ui);
|
||||
|
||||
/* 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());
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue