From b4963d9f709417040ef2f0bffc6ea841558cee2f Mon Sep 17 00:00:00 2001
From: Ghislain MARY <ghislain.mary@belledonne-communications.com>
Date: Fri, 29 Aug 2014 14:39:34 +0200
Subject: [PATCH] Put call log related code in its own files.

---
 build/android/Android.mk      |   3 +-
 build/wp8/LibLinphone.vcxproj |   1 +
 coreapi/CMakeLists.txt        |  15 +-
 coreapi/Makefile.am           |   3 +-
 coreapi/call_log.c            | 260 ++++++++++++++++++++++++++++
 coreapi/call_log.h            | 224 ++++++++++++++++++++++++
 coreapi/linphonecore.c        | 309 +---------------------------------
 coreapi/linphonecore.h        | 100 ++++-------
 coreapi/private.h             |   1 +
 9 files changed, 544 insertions(+), 372 deletions(-)
 create mode 100644 coreapi/call_log.c
 create mode 100644 coreapi/call_log.h

diff --git a/build/android/Android.mk b/build/android/Android.mk
index 817aba539c..6310550c4f 100755
--- a/build/android/Android.mk
+++ b/build/android/Android.mk
@@ -65,7 +65,8 @@ LOCAL_SRC_FILES := \
 	xml2lpc.c \
 	lpc2xml.c \
 	remote_provisioning.c \
-	quality_reporting.c
+	quality_reporting.c \
+	call_log.c
 
 ifndef LINPHONE_VERSION
 LINPHONE_VERSION = "Devel"
diff --git a/build/wp8/LibLinphone.vcxproj b/build/wp8/LibLinphone.vcxproj
index 797b2517d8..df4135e680 100644
--- a/build/wp8/LibLinphone.vcxproj
+++ b/build/wp8/LibLinphone.vcxproj
@@ -107,6 +107,7 @@
     <ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_publish.c" />
     <ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_registration.c" />
     <ClCompile Include="..\..\coreapi\bellesip_sal\sal_sdp.c" />
+    <ClCompile Include="..\..\coreapi\call_log.c" />
     <ClCompile Include="..\..\coreapi\callbacks.c" />
     <ClCompile Include="..\..\coreapi\chat.c" />
     <ClCompile Include="..\..\coreapi\conference.c" />
diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt
index ab707ce696..6323a1adce 100644
--- a/coreapi/CMakeLists.txt
+++ b/coreapi/CMakeLists.txt
@@ -42,6 +42,7 @@ set(SOURCE_FILES
 	bellesip_sal/sal_op_registration.c
 	bellesip_sal/sal_sdp.c
 	callbacks.c
+	call_log.c
 	chat.c
 	conference.c
 	ec-calibrator.c
@@ -139,7 +140,19 @@ install(TARGETS linphone
 )
 
 
-file(GLOB HEADER_FILES "*.h")
+set(HEADER_FILES
+	call_log.h
+	event.h
+	linphonecore.h
+	linphonecore_utils.h
+	linphonefriend.h
+	linphonepresence.h
+	linphone_tunnel.h
+	lpc2xml.h
+	lpconfig.h
+	sipsetup.h
+	xml2lpc.h
+)
 
 install(FILES ${HEADER_FILES}
 	DESTINATION include/linphone
diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am
index 5ae75edd84..a359970e9d 100644
--- a/coreapi/Makefile.am
+++ b/coreapi/Makefile.am
@@ -24,7 +24,7 @@ CLEANFILES=$(GITVERSION_FILE)
 ## Process this file with automake to produce Makefile.in
 linphone_includedir=$(includedir)/linphone
 
-linphone_include_HEADERS=linphonecore.h linphonefriend.h linphonepresence.h linphonecore_utils.h lpconfig.h sipsetup.h event.h xml2lpc.h lpc2xml.h linphone_tunnel.h
+linphone_include_HEADERS=linphonecore.h linphonefriend.h linphonepresence.h linphonecore_utils.h lpconfig.h sipsetup.h event.h xml2lpc.h lpc2xml.h linphone_tunnel.h call_log.h
 
 lib_LTLIBRARIES=liblinphone.la
 
@@ -59,6 +59,7 @@ liblinphone_la_SOURCES=\
 	lpc2xml.c \
 	remote_provisioning.c \
 	quality_reporting.c quality_reporting.h\
+	call_log.c \
 	$(GITVERSION_FILE)
 
 if BUILD_UPNP
diff --git a/coreapi/call_log.c b/coreapi/call_log.c
new file mode 100644
index 0000000000..811f8c4374
--- /dev/null
+++ b/coreapi/call_log.c
@@ -0,0 +1,260 @@
+/*
+linphone
+Copyright (C) 2010-2014  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"
+
+
+/*******************************************************************************
+ * Internal functions                                                          *
+ ******************************************************************************/
+
+static void set_call_log_date(LinphoneCallLog *cl, time_t start_time){
+	struct tm loctime;
+#ifdef WIN32
+#if !defined(_WIN32_WCE)
+	loctime=*localtime(&start_time);
+	/*FIXME*/
+#endif /*_WIN32_WCE*/
+#else
+	localtime_r(&start_time,&loctime);
+#endif
+	my_strftime(cl->start_date,sizeof(cl->start_date),"%c",&loctime);
+}
+
+/*******************************************************************************
+ * Private functions                                                           *
+ ******************************************************************************/
+
+void call_logs_write_to_config_file(LinphoneCore *lc){
+	MSList *elem;
+	char logsection[32];
+	int i;
+	char *tmp;
+	LpConfig *cfg=lc->config;
+
+	if (linphone_core_get_global_state (lc)==LinphoneGlobalStartup) return;
+
+	for(i=0,elem=lc->call_logs;elem!=NULL;elem=elem->next,++i){
+		LinphoneCallLog *cl=(LinphoneCallLog*)elem->data;
+		snprintf(logsection,sizeof(logsection),"call_log_%i",i);
+		lp_config_clean_section(cfg,logsection);
+		lp_config_set_int(cfg,logsection,"dir",cl->dir);
+		lp_config_set_int(cfg,logsection,"status",cl->status);
+		tmp=linphone_address_as_string(cl->from);
+		lp_config_set_string(cfg,logsection,"from",tmp);
+		ms_free(tmp);
+		tmp=linphone_address_as_string(cl->to);
+		lp_config_set_string(cfg,logsection,"to",tmp);
+		ms_free(tmp);
+		if (cl->start_date_time)
+			lp_config_set_int64(cfg,logsection,"start_date_time",(int64_t)cl->start_date_time);
+		else lp_config_set_string(cfg,logsection,"start_date",cl->start_date);
+		lp_config_set_int(cfg,logsection,"duration",cl->duration);
+		if (cl->refkey) lp_config_set_string(cfg,logsection,"refkey",cl->refkey);
+		lp_config_set_float(cfg,logsection,"quality",cl->quality);
+		lp_config_set_int(cfg,logsection,"video_enabled", cl->video_enabled);
+		lp_config_set_string(cfg,logsection,"call_id",cl->call_id);
+	}
+	for(;i<lc->max_call_logs;++i){
+		snprintf(logsection,sizeof(logsection),"call_log_%i",i);
+		lp_config_clean_section(cfg,logsection);
+	}
+}
+
+void call_logs_read_from_config_file(LinphoneCore *lc){
+	char logsection[32];
+	int i;
+	const char *tmp;
+	uint64_t sec;
+	LpConfig *cfg=lc->config;
+	for(i=0;;++i){
+		snprintf(logsection,sizeof(logsection),"call_log_%i",i);
+		if (lp_config_has_section(cfg,logsection)){
+			LinphoneCallLog *cl=ms_new0(LinphoneCallLog,1);
+			cl->dir=lp_config_get_int(cfg,logsection,"dir",0);
+			cl->status=lp_config_get_int(cfg,logsection,"status",0);
+			tmp=lp_config_get_string(cfg,logsection,"from",NULL);
+			if (tmp) cl->from=linphone_address_new(tmp);
+			tmp=lp_config_get_string(cfg,logsection,"to",NULL);
+			if (tmp) cl->to=linphone_address_new(tmp);
+			sec=lp_config_get_int64(cfg,logsection,"start_date_time",0);
+			if (sec) {
+				/*new call log format with date expressed in seconds */
+				cl->start_date_time=(time_t)sec;
+				set_call_log_date(cl,cl->start_date_time);
+			}else{
+				tmp=lp_config_get_string(cfg,logsection,"start_date",NULL);
+				if (tmp) {
+					strncpy(cl->start_date,tmp,sizeof(cl->start_date));
+					cl->start_date_time=string_to_time(cl->start_date);
+				}
+			}
+			cl->duration=lp_config_get_int(cfg,logsection,"duration",0);
+			tmp=lp_config_get_string(cfg,logsection,"refkey",NULL);
+			if (tmp) cl->refkey=ms_strdup(tmp);
+			cl->quality=lp_config_get_float(cfg,logsection,"quality",-1);
+			cl->video_enabled=lp_config_get_int(cfg,logsection,"video_enabled",0);
+			tmp=lp_config_get_string(cfg,logsection,"call_id",NULL);
+			if (tmp) cl->call_id=ms_strdup(tmp);
+			lc->call_logs=ms_list_append(lc->call_logs,cl);
+		}else break;
+	}
+}
+
+
+/*******************************************************************************
+ * Public functions                                                            *
+ ******************************************************************************/
+
+const char *linphone_call_log_get_call_id(const LinphoneCallLog *cl){
+	return cl->call_id;
+}
+
+LinphoneCallDir linphone_call_log_get_dir(LinphoneCallLog *cl){
+	return cl->dir;
+}
+
+int linphone_call_log_get_duration(LinphoneCallLog *cl){
+	return cl->duration;
+}
+
+LinphoneAddress *linphone_call_log_get_from_address(LinphoneCallLog *cl){
+	return cl->from;
+}
+
+const rtp_stats_t *linphone_call_log_get_local_stats(const LinphoneCallLog *cl){
+	return &cl->local_stats;
+}
+
+float linphone_call_log_get_quality(LinphoneCallLog *cl){
+	return cl->quality;
+}
+
+const char *linphone_call_log_get_ref_key(const LinphoneCallLog *cl){
+	return cl->refkey;
+}
+
+LinphoneAddress *linphone_call_log_get_remote_address(LinphoneCallLog *cl){
+	return (cl->dir == LinphoneCallIncoming) ? cl->from : cl->to;
+}
+
+const rtp_stats_t *linphone_call_log_get_remote_stats(const LinphoneCallLog *cl){
+	return &cl->remote_stats;
+}
+
+time_t linphone_call_log_get_start_date(LinphoneCallLog *cl){
+	return cl->start_date_time;
+}
+
+LinphoneCallStatus linphone_call_log_get_status(LinphoneCallLog *cl){
+	return cl->status;
+}
+
+LinphoneAddress *linphone_call_log_get_to_address(LinphoneCallLog *cl){
+	return cl->to;
+}
+
+void linphone_call_log_set_ref_key(LinphoneCallLog *cl, const char *refkey){
+	if (cl->refkey!=NULL){
+		ms_free(cl->refkey);
+		cl->refkey=NULL;
+	}
+	if (refkey) cl->refkey=ms_strdup(refkey);
+}
+
+char * linphone_call_log_to_str(LinphoneCallLog *cl){
+	char *status;
+	char *tmp;
+	char *from=linphone_address_as_string (cl->from);
+	char *to=linphone_address_as_string (cl->to);
+	switch(cl->status){
+		case LinphoneCallAborted:
+			status=_("aborted");
+			break;
+		case LinphoneCallSuccess:
+			status=_("completed");
+			break;
+		case LinphoneCallMissed:
+			status=_("missed");
+			break;
+		default:
+			status="unknown";
+	}
+	tmp=ortp_strdup_printf(_("%s at %s\nFrom: %s\nTo: %s\nStatus: %s\nDuration: %i mn %i sec\n"),
+			(cl->dir==LinphoneCallIncoming) ? _("Incoming call") : _("Outgoing call"),
+			cl->start_date,
+			from,
+			to,
+			status,
+			cl->duration/60,
+			cl->duration%60);
+	ms_free(from);
+	ms_free(to);
+	return tmp;
+}
+
+bool_t linphone_call_log_video_enabled(LinphoneCallLog *cl) {
+	return cl->video_enabled;
+}
+
+
+/*******************************************************************************
+ * Reference and user data handling functions                                  *
+ ******************************************************************************/
+
+void *linphone_call_log_get_user_data(const LinphoneCallLog *cl){
+	return cl->user_pointer;
+}
+
+void linphone_call_log_set_user_data(LinphoneCallLog *cl, void *ud){
+	cl->user_pointer=ud;
+}
+
+
+/*******************************************************************************
+ * Constructor and destructor functions                                        *
+ ******************************************************************************/
+
+void linphone_call_log_destroy(LinphoneCallLog *cl){
+	if (cl->from!=NULL) linphone_address_destroy(cl->from);
+	if (cl->to!=NULL) linphone_address_destroy(cl->to);
+	if (cl->refkey!=NULL) ms_free(cl->refkey);
+	if (cl->call_id) ms_free(cl->call_id);
+	if (cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]!=NULL) linphone_reporting_destroy(cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]);
+	if (cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]!=NULL) linphone_reporting_destroy(cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]);
+
+	ms_free(cl);
+}
+
+LinphoneCallLog * linphone_call_log_new(LinphoneCall *call, LinphoneAddress *from, LinphoneAddress *to){
+	LinphoneCallLog *cl=ms_new0(LinphoneCallLog,1);
+	cl->dir=call->dir;
+	cl->start_date_time=time(NULL);
+	set_call_log_date(cl,cl->start_date_time);
+	cl->from=from;
+	cl->to=to;
+	cl->status=LinphoneCallAborted; /*default status*/
+	cl->quality=-1;
+
+	cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]=linphone_reporting_new();
+	cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]=linphone_reporting_new();
+	return cl;
+}
diff --git a/coreapi/call_log.h b/coreapi/call_log.h
new file mode 100644
index 0000000000..e69f170982
--- /dev/null
+++ b/coreapi/call_log.h
@@ -0,0 +1,224 @@
+/*
+linphone
+Copyright (C) 2010-2014  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_CALL_LOG_H__
+#define __LINPHONE_CALL_LOG_H__
+
+/**
+ * @addtogroup call_logs
+ * @{
+**/
+
+
+/*******************************************************************************
+ * Structures and enums                                                        *
+ ******************************************************************************/
+
+/**
+ * Enum representing the direction of a call.
+**/
+enum _LinphoneCallDir {
+	LinphoneCallOutgoing, /**< outgoing calls*/
+	LinphoneCallIncoming  /**< incoming calls*/
+};
+
+/**
+ * Typedef for enum
+**/
+typedef enum _LinphoneCallDir LinphoneCallDir;
+
+/**
+ * Enum representing the status of a call
+**/
+typedef enum _LinphoneCallStatus {
+	LinphoneCallSuccess, /**< The call was sucessful */
+	LinphoneCallAborted, /**< The call was aborted */
+	LinphoneCallMissed, /**< The call was missed (unanswered) */
+	LinphoneCallDeclined /**< The call was declined, either locally or by remote end */
+} LinphoneCallStatus;
+
+/**
+ * Structure representing a call log.
+**/
+typedef struct _LinphoneCallLog LinphoneCallLog;
+
+
+/*******************************************************************************
+ * Public functions                                                            *
+ ******************************************************************************/
+
+/**
+ * Get the call ID used by the call.
+ * @param[in] cl LinphoneCallLog object
+ * @return The call ID used by the call as a string.
+**/
+LINPHONE_PUBLIC const char * linphone_call_log_get_call_id(const LinphoneCallLog *cl);
+
+/**
+ * Get the direction of the call.
+ * @param[in] cl LinphoneCallLog object
+ * @return The direction of the call.
+**/
+LINPHONE_PUBLIC LinphoneCallDir linphone_call_log_get_dir(LinphoneCallLog *cl);
+
+/**
+ * Get the duration of the call.
+ * @param[in] cl LinphoneCallLog object
+ * @return The duration of the call in seconds.
+**/
+LINPHONE_PUBLIC int linphone_call_log_get_duration(LinphoneCallLog *cl);
+
+/**
+ * Get the origin address (ie from) of the call.
+ * @param[in] cl LinphoneCallLog object
+ * @return The origin address (ie from) of the call.
+**/
+LINPHONE_PUBLIC LinphoneAddress * linphone_call_log_get_from_address(LinphoneCallLog *cl);
+
+/**
+ * Get the RTP statistics computed locally regarding the call.
+ * @param[in] cl LinphoneCallLog object
+ * @return The RTP statistics that have been computed locally for the call.
+**/
+LINPHONE_PUBLIC const rtp_stats_t * linphone_call_log_get_local_stats(const LinphoneCallLog *cl);
+
+/**
+ * Get the overall quality indication of the call.
+ * @param[in] cl LinphoneCallLog object
+ * @return The overall quality indication of the call.
+**/
+LINPHONE_PUBLIC float linphone_call_log_get_quality(LinphoneCallLog *cl);
+
+/**
+ * Get the persistent reference key associated to the call log.
+ *
+ * The reference key can be for example an id to an external database.
+ * It is stored in the config file, thus can survive to process exits/restarts.
+ *
+ * @param[in] cl LinphoneCallLog object
+ * @return The reference key string that has been associated to the call log, or NULL if none has been associated.
+**/
+LINPHONE_PUBLIC const char * linphone_call_log_get_ref_key(const LinphoneCallLog *cl);
+
+/**
+ * Get the remote address (that is from or to depending on call direction).
+ * @param[in] cl LinphoneCallLog object
+ * @return The remote address of the call.
+**/
+LINPHONE_PUBLIC LinphoneAddress * linphone_call_log_get_remote_address(LinphoneCallLog *cl);
+
+/**
+ * Get the RTP statistics computed by the remote end and sent back via RTCP.
+ * @note Not implemented yet.
+ * @param[in] cl LinphoneCallLog object
+ * @return The RTP statistics that have been computed by the remote end for the call.
+**/
+LINPHONE_PUBLIC const rtp_stats_t * linphone_call_log_get_remote_stats(const LinphoneCallLog *cl);
+
+/**
+ * Get the start date of the call.
+ * @param[in] cl LinphoneCallLog object
+ * @return The date of the beginning of the call.
+**/
+LINPHONE_PUBLIC time_t linphone_call_log_get_start_date(LinphoneCallLog *cl);
+
+/**
+ * Get the status of the call.
+ * @param[in] cl LinphoneCallLog object
+ * @return The status of the call.
+**/
+LINPHONE_PUBLIC LinphoneCallStatus linphone_call_log_get_status(LinphoneCallLog *cl);
+
+/**
+ * Get the destination address (ie to) of the call.
+ * @param[in] cl LinphoneCallLog object
+ * @return The destination address (ie to) of the call.
+**/
+LINPHONE_PUBLIC LinphoneAddress * linphone_call_log_get_to_address(LinphoneCallLog *cl);
+
+/**
+ * Associate a persistent reference key to the call log.
+ *
+ * The reference key can be for example an id to an external database.
+ * It is stored in the config file, thus can survive to process exits/restarts.
+ *
+ * @param[in] cl LinphoneCallLog object
+ * @param[in] refkey The reference key string to associate to the call log.
+**/
+LINPHONE_PUBLIC void linphone_call_log_set_ref_key(LinphoneCallLog *cl, const char *refkey);
+
+/**
+ * Tell whether video was enabled at the end of the call or not.
+ * @param[in] cl LinphoneCallLog object
+ * @return A boolean value telling whether video was enabled at the end of the call.
+**/
+LINPHONE_PUBLIC bool_t linphone_call_log_video_enabled(LinphoneCallLog *cl);
+
+/**
+ * Get a human readable string describing the call.
+ * @note: the returned string must be freed by the application (use ms_free()).
+ * @param[in] cl LinphoneCallLog object
+ * @return A human readable string describing the call.
+**/
+LINPHONE_PUBLIC char * linphone_call_log_to_str(LinphoneCallLog *cl);
+
+
+/*******************************************************************************
+ * Reference and user data handling functions                                  *
+ ******************************************************************************/
+
+/**
+ * Get the user data associated with the call log.
+ * @param[in] cl LinphoneCallLog object
+ * @return The user data associated with the call log.
+**/
+LINPHONE_PUBLIC void *linphone_call_log_get_user_data(const LinphoneCallLog *cl);
+
+/**
+ * Assign a user data to the call log.
+ * @param[in] cl LinphoneCallLog object
+ * @param[in] ud The user data to associate with the call log.
+**/
+LINPHONE_PUBLIC void linphone_call_log_set_user_data(LinphoneCallLog *cl, void *ud);
+
+
+/*******************************************************************************
+ * DEPRECATED                                                                  *
+ ******************************************************************************/
+
+/** @deprecated Use linphone_call_log_get_from_address() instead. */
+#define linphone_call_log_get_from(cl) linphone_call_log_get_from_address(cl)
+
+/** @deprecated Use linphone_call_log_get_to_address() instead. */
+#define linphone_call_log_get_to(cl) linphone_call_log_get_to_address(cl)
+
+/** @deprecated Use linphone_call_log_set_user_data() instead. */
+#define linphone_call_log_set_user_pointer(cl, ud) linphone_call_log_set_user_data(cl, ud)
+
+/** @deprecated Use linphone_call_log_get_user_data() instead. */
+#define linphone_call_log_get_user_pointer(cl) linphone_call_log_get_user_data(cl)
+
+
+/**
+ * @}
+**/
+
+
+#endif /* __LINPHONE_CALL_LOG_H__ */
diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c
index a926bee08a..985b23d48d 100644
--- a/coreapi/linphonecore.c
+++ b/coreapi/linphonecore.c
@@ -107,70 +107,6 @@ static size_t my_strftime(char *s, size_t max, const char  *fmt,  const struct t
 	return strftime(s, max, fmt, tm);
 }
 
-static void set_call_log_date(LinphoneCallLog *cl, time_t start_time){
-	struct tm loctime;
-#ifdef WIN32
-#if !defined(_WIN32_WCE)
-	loctime=*localtime(&start_time);
-	/*FIXME*/
-#endif /*_WIN32_WCE*/
-#else
-	localtime_r(&start_time,&loctime);
-#endif
-	my_strftime(cl->start_date,sizeof(cl->start_date),"%c",&loctime);
-}
-
-LinphoneCallLog * linphone_call_log_new(LinphoneCall *call, LinphoneAddress *from, LinphoneAddress *to){
-	LinphoneCallLog *cl=ms_new0(LinphoneCallLog,1);
-	cl->dir=call->dir;
-	cl->start_date_time=time(NULL);
-	set_call_log_date(cl,cl->start_date_time);
-	cl->from=from;
-	cl->to=to;
-	cl->status=LinphoneCallAborted; /*default status*/
-	cl->quality=-1;
-
-	cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]=linphone_reporting_new();
-	cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]=linphone_reporting_new();
-	return cl;
-}
-
-void call_logs_write_to_config_file(LinphoneCore *lc){
-	MSList *elem;
-	char logsection[32];
-	int i;
-	char *tmp;
-	LpConfig *cfg=lc->config;
-
-	if (linphone_core_get_global_state (lc)==LinphoneGlobalStartup) return;
-
-	for(i=0,elem=lc->call_logs;elem!=NULL;elem=elem->next,++i){
-		LinphoneCallLog *cl=(LinphoneCallLog*)elem->data;
-		snprintf(logsection,sizeof(logsection),"call_log_%i",i);
-		lp_config_clean_section(cfg,logsection);
-		lp_config_set_int(cfg,logsection,"dir",cl->dir);
-		lp_config_set_int(cfg,logsection,"status",cl->status);
-		tmp=linphone_address_as_string(cl->from);
-		lp_config_set_string(cfg,logsection,"from",tmp);
-		ms_free(tmp);
-		tmp=linphone_address_as_string(cl->to);
-		lp_config_set_string(cfg,logsection,"to",tmp);
-		ms_free(tmp);
-		if (cl->start_date_time)
-			lp_config_set_int64(cfg,logsection,"start_date_time",(int64_t)cl->start_date_time);
-		else lp_config_set_string(cfg,logsection,"start_date",cl->start_date);
-		lp_config_set_int(cfg,logsection,"duration",cl->duration);
-		if (cl->refkey) lp_config_set_string(cfg,logsection,"refkey",cl->refkey);
-		lp_config_set_float(cfg,logsection,"quality",cl->quality);
-		lp_config_set_int(cfg,logsection,"video_enabled", cl->video_enabled);
-		lp_config_set_string(cfg,logsection,"call_id",cl->call_id);
-	}
-	for(;i<lc->max_call_logs;++i){
-		snprintf(logsection,sizeof(logsection),"call_log_%i",i);
-		lp_config_clean_section(cfg,logsection);
-	}
-}
-
 static time_t string_to_time(const char *date){
 #ifndef WIN32
 	struct tm tmtime={0};
@@ -181,230 +117,6 @@ static time_t string_to_time(const char *date){
 #endif
 }
 
-static void call_logs_read_from_config_file(LinphoneCore *lc){
-	char logsection[32];
-	int i;
-	const char *tmp;
-	uint64_t sec;
-	LpConfig *cfg=lc->config;
-	for(i=0;;++i){
-		snprintf(logsection,sizeof(logsection),"call_log_%i",i);
-		if (lp_config_has_section(cfg,logsection)){
-			LinphoneCallLog *cl=ms_new0(LinphoneCallLog,1);
-			cl->dir=lp_config_get_int(cfg,logsection,"dir",0);
-			cl->status=lp_config_get_int(cfg,logsection,"status",0);
-			tmp=lp_config_get_string(cfg,logsection,"from",NULL);
-			if (tmp) cl->from=linphone_address_new(tmp);
-			tmp=lp_config_get_string(cfg,logsection,"to",NULL);
-			if (tmp) cl->to=linphone_address_new(tmp);
-			sec=lp_config_get_int64(cfg,logsection,"start_date_time",0);
-			if (sec) {
-				/*new call log format with date expressed in seconds */
-				cl->start_date_time=(time_t)sec;
-				set_call_log_date(cl,cl->start_date_time);
-			}else{
-				tmp=lp_config_get_string(cfg,logsection,"start_date",NULL);
-				if (tmp) {
-					strncpy(cl->start_date,tmp,sizeof(cl->start_date));
-					cl->start_date_time=string_to_time(cl->start_date);
-				}
-			}
-			cl->duration=lp_config_get_int(cfg,logsection,"duration",0);
-			tmp=lp_config_get_string(cfg,logsection,"refkey",NULL);
-			if (tmp) cl->refkey=ms_strdup(tmp);
-			cl->quality=lp_config_get_float(cfg,logsection,"quality",-1);
-			cl->video_enabled=lp_config_get_int(cfg,logsection,"video_enabled",0);
-			tmp=lp_config_get_string(cfg,logsection,"call_id",NULL);
-			if (tmp) cl->call_id=ms_strdup(tmp);
-			lc->call_logs=ms_list_append(lc->call_logs,cl);
-		}else break;
-	}
-}
-
-
-
-/**
- * @addtogroup call_logs
- * @{
-**/
-
-/**
- * Returns a human readable string describing the call.
- *
- * @note: the returned char* must be freed by the application (use ms_free()).
-**/
-char * linphone_call_log_to_str(LinphoneCallLog *cl){
-	char *status;
-	char *tmp;
-	char *from=linphone_address_as_string (cl->from);
-	char *to=linphone_address_as_string (cl->to);
-	switch(cl->status){
-		case LinphoneCallAborted:
-			status=_("aborted");
-			break;
-		case LinphoneCallSuccess:
-			status=_("completed");
-			break;
-		case LinphoneCallMissed:
-			status=_("missed");
-			break;
-		default:
-			status="unknown";
-	}
-	tmp=ortp_strdup_printf(_("%s at %s\nFrom: %s\nTo: %s\nStatus: %s\nDuration: %i mn %i sec\n"),
-			(cl->dir==LinphoneCallIncoming) ? _("Incoming call") : _("Outgoing call"),
-			cl->start_date,
-			from,
-			to,
-			status,
-			cl->duration/60,
-			cl->duration%60);
-	ms_free(from);
-	ms_free(to);
-	return tmp;
-}
-
-/**
- * Returns RTP statistics computed locally regarding the call.
- *
-**/
-const rtp_stats_t *linphone_call_log_get_local_stats(const LinphoneCallLog *cl){
-	return &cl->local_stats;
-}
-
-/**
- * Returns RTP statistics computed by remote end and sent back via RTCP.
- *
- * @note Not implemented yet.
-**/
-const rtp_stats_t *linphone_call_log_get_remote_stats(const LinphoneCallLog *cl){
-	return &cl->remote_stats;
-}
-
-const char *linphone_call_log_get_call_id(const LinphoneCallLog *cl){
-	return cl->call_id;
-}
-
-/**
- * Assign a user pointer to the call log.
-**/
-void linphone_call_log_set_user_data(LinphoneCallLog *cl, void *up){
-	cl->user_pointer=up;
-}
-
-/**
- * Returns the user pointer associated with the call log.
-**/
-void *linphone_call_log_get_user_data(const LinphoneCallLog *cl){
-	return cl->user_pointer;
-}
-
-
-
-/**
- * Associate a persistent reference key to the call log.
- *
- * The reference key can be for example an id to an external database.
- * It is stored in the config file, thus can survive to process exits/restarts.
- *
-**/
-void linphone_call_log_set_ref_key(LinphoneCallLog *cl, const char *refkey){
-	if (cl->refkey!=NULL){
-		ms_free(cl->refkey);
-		cl->refkey=NULL;
-	}
-	if (refkey) cl->refkey=ms_strdup(refkey);
-}
-
-/**
- * Get the persistent reference key associated to the call log.
- *
- * The reference key can be for example an id to an external database.
- * It is stored in the config file, thus can survive to process exits/restarts.
- *
-**/
-const char *linphone_call_log_get_ref_key(const LinphoneCallLog *cl){
-	return cl->refkey;
-}
-
-/**
- * Returns origin address (ie from) of the call.
- * @param[in] cl LinphoneCallLog object
- * @return The origin address (ie from) of the call.
-**/
-LinphoneAddress *linphone_call_log_get_from_address(LinphoneCallLog *cl){
-	return cl->from;
-}
-
-/**
- * Returns destination address (ie to) of the call.
- * @param[in] cl LinphoneCallLog object
- * @return The destination address (ie to) of the call.
-**/
-LinphoneAddress *linphone_call_log_get_to_address(LinphoneCallLog *cl){
-	return cl->to;
-}
-
-/**
- * Returns remote address (that is from or to depending on call direction).
-**/
-LinphoneAddress *linphone_call_log_get_remote_address(LinphoneCallLog *cl){
-	return (cl->dir == LinphoneCallIncoming) ? cl->from : cl->to;
-}
-
-/**
- * Returns the direction of the call.
-**/
-LinphoneCallDir linphone_call_log_get_dir(LinphoneCallLog *cl){
-	return cl->dir;
-}
-
-/**
- * Returns the status of the call.
-**/
-LinphoneCallStatus linphone_call_log_get_status(LinphoneCallLog *cl){
-	return cl->status;
-}
-
-/**
- * Returns the start date of the call, expressed as a POSIX time_t.
-**/
-time_t linphone_call_log_get_start_date(LinphoneCallLog *cl){
-	return cl->start_date_time;
-}
-
-/**
- * Returns duration of the call.
-**/
-int linphone_call_log_get_duration(LinphoneCallLog *cl){
-	return cl->duration;
-}
-
-/**
- * Returns overall quality indication of the call.
-**/
-float linphone_call_log_get_quality(LinphoneCallLog *cl){
-	return cl->quality;
-}
-/**
- * return true if video was enabled at the end of the call
- */
-bool_t linphone_call_log_video_enabled(LinphoneCallLog *cl) {
-	return cl->video_enabled;
-}
-/** @} */
-
-void linphone_call_log_destroy(LinphoneCallLog *cl){
-	if (cl->from!=NULL) linphone_address_destroy(cl->from);
-	if (cl->to!=NULL) linphone_address_destroy(cl->to);
-	if (cl->refkey!=NULL) ms_free(cl->refkey);
-	if (cl->call_id) ms_free(cl->call_id);
-	if (cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]!=NULL) linphone_reporting_destroy(cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]);
-	if (cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]!=NULL) linphone_reporting_destroy(cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]);
-
-	ms_free(cl);
-}
-
 /**
  * Returns TRUE if the LinphoneCall asked to autoanswer
  *
@@ -4791,22 +4503,16 @@ LinphoneFirewallPolicy linphone_core_get_firewall_policy(const LinphoneCore *lc)
 		return LinphonePolicyNoFirewall;
 }
 
-/**
- * Get the list of call logs (past calls).
- * @param[in] lc The LinphoneCore object
- * @return \mslist{LinphoneCallLog}
- *
- * @ingroup call_logs
-**/
+
+
+/*******************************************************************************
+ * Call log related functions                                                  *
+ ******************************************************************************/
+
 const MSList * linphone_core_get_call_logs(LinphoneCore *lc){
 	return lc->call_logs;
 }
 
-/**
- * Erase the call log.
- *
- * @ingroup call_logs
-**/
 void linphone_core_clear_call_logs(LinphoneCore *lc){
 	lc->missed_calls=0;
 	ms_list_for_each(lc->call_logs,(void (*)(void*))linphone_call_log_destroy);
@@ -4828,6 +4534,9 @@ void linphone_core_remove_call_log(LinphoneCore *lc, LinphoneCallLog *cl){
 	linphone_call_log_destroy(cl);
 }
 
+
+
+
 static void toggle_video_preview(LinphoneCore *lc, bool_t val){
 #ifdef VIDEO_ENABLED
 	if (val){
diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h
index cb3b173ee9..0a35554c48 100644
--- a/coreapi/linphonecore.h
+++ b/coreapi/linphonecore.h
@@ -292,9 +292,11 @@ LINPHONE_PUBLIC int linphone_payload_type_get_channels(const LinphonePayloadType
 #ifdef IN_LINPHONE
 #include "linphonefriend.h"
 #include "event.h"
+#include "call_log.h"
 #else
 #include "linphone/linphonefriend.h"
 #include "linphone/event.h"
+#include "linphone/call_log.h"
 #endif
 
 LINPHONE_PUBLIC	LinphoneAddress * linphone_address_new(const char *addr);
@@ -332,40 +334,6 @@ LINPHONE_PUBLIC LinphoneAddress * linphone_core_create_address(LinphoneCore *lc,
 struct _SipSetupContext;
 
 
-/**
- * Enum representing the direction of a call.
- * @ingroup call_logs
-**/
-enum _LinphoneCallDir {
-	LinphoneCallOutgoing, /**< outgoing calls*/
-	LinphoneCallIncoming  /**< incoming calls*/
-};
-
-/**
- * Typedef for enum
- * @ingroup call_logs
-**/
-typedef enum _LinphoneCallDir LinphoneCallDir;
-
-/**
- * Enum representing the status of a call
- * @ingroup call_logs
-**/
-typedef enum _LinphoneCallStatus {
-	LinphoneCallSuccess, /**< The call was sucessful*/
-	LinphoneCallAborted, /**< The call was aborted */
-	LinphoneCallMissed, /**< The call was missed (unanswered)*/
-	LinphoneCallDeclined /**< The call was declined, either locally or by remote end*/
-} LinphoneCallStatus;
-
-/**
- * Structure representing a call log.
- *
- * @ingroup call_logs
- *
-**/
-typedef struct _LinphoneCallLog LinphoneCallLog;
-
 /**
  * Enum describing type of media encryption types.
  * @ingroup media_parameters
@@ -388,32 +356,6 @@ typedef enum _LinphoneMediaEncryption LinphoneMediaEncryption;
 **/
 LINPHONE_PUBLIC const char *linphone_media_encryption_to_string(LinphoneMediaEncryption menc);
 
-/*public: */
-/** @deprecated Use linphone_call_log_get_from_address() instead. */
-#define linphone_call_log_get_from(cl) linphone_call_log_get_from_address(cl)
-LINPHONE_PUBLIC	LinphoneAddress *linphone_call_log_get_from_address(LinphoneCallLog *cl);
-/** @deprecated Use linphone_call_log_get_to_address() instead. */
-#define linphone_call_log_get_to(cl) linphone_call_log_get_to_address(cl)
-LINPHONE_PUBLIC	LinphoneAddress *linphone_call_log_get_to_address(LinphoneCallLog *cl);
-LINPHONE_PUBLIC	LinphoneAddress *linphone_call_log_get_remote_address(LinphoneCallLog *cl);
-LINPHONE_PUBLIC	LinphoneCallDir linphone_call_log_get_dir(LinphoneCallLog *cl);
-LINPHONE_PUBLIC	LinphoneCallStatus linphone_call_log_get_status(LinphoneCallLog *cl);
-LINPHONE_PUBLIC	bool_t linphone_call_log_video_enabled(LinphoneCallLog *cl);
-LINPHONE_PUBLIC	time_t linphone_call_log_get_start_date(LinphoneCallLog *cl);
-LINPHONE_PUBLIC	int linphone_call_log_get_duration(LinphoneCallLog *cl);
-LINPHONE_PUBLIC	float linphone_call_log_get_quality(LinphoneCallLog *cl);
-/** @deprecated Use linphone_call_log_set_user_data() instead. */
-#define linphone_call_log_set_user_pointer(cl, ud) linphone_call_log_set_user_data(cl, ud)
-LINPHONE_PUBLIC	void linphone_call_log_set_user_data(LinphoneCallLog *cl, void *up);
-/** @deprecated Use linphone_call_log_get_user_data() instead. */
-#define linphone_call_log_get_user_pointer(cl) linphone_call_log_get_user_data(cl)
-LINPHONE_PUBLIC	void *linphone_call_log_get_user_data(const LinphoneCallLog *cl);
-void linphone_call_log_set_ref_key(LinphoneCallLog *cl, const char *refkey);
-const char *linphone_call_log_get_ref_key(const LinphoneCallLog *cl);
-LINPHONE_PUBLIC	const rtp_stats_t *linphone_call_log_get_local_stats(const LinphoneCallLog *cl);
-LINPHONE_PUBLIC	const rtp_stats_t *linphone_call_log_get_remote_stats(const LinphoneCallLog *cl);
-LINPHONE_PUBLIC	const char *linphone_call_log_get_call_id(const LinphoneCallLog *cl);
-LINPHONE_PUBLIC	char * linphone_call_log_to_str(LinphoneCallLog *cl);
 
 /**
  * Private structure definition for LinphoneCallParams.
@@ -2457,34 +2399,54 @@ bool_t linphone_core_get_rtp_no_xmit_on_audio_mute(const LinphoneCore *lc);
 void linphone_core_set_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, bool_t val);
 
 
-/* returns a list of LinphoneCallLog */
-LINPHONE_PUBLIC	const MSList * linphone_core_get_call_logs(LinphoneCore *lc);
-LINPHONE_PUBLIC	void linphone_core_clear_call_logs(LinphoneCore *lc);
+/*******************************************************************************
+ * Call log related functions                                                  *
+ ******************************************************************************/
+
+/**
+ * @addtogroup call_logs
+ * @{
+**/
+
+/**
+ * Get the list of call logs (past calls).
+ * @param[in] lc LinphoneCore object
+ * @return \mslist{LinphoneCallLog}
+**/
+LINPHONE_PUBLIC const MSList * linphone_core_get_call_logs(LinphoneCore *lc);
+
+/**
+ * Erase the call log.
+ * @param[in] lc LinphoneCore object
+**/
+LINPHONE_PUBLIC void linphone_core_clear_call_logs(LinphoneCore *lc);
 
 /**
  * Get the number of missed calls.
  * Once checked, this counter can be reset with linphone_core_reset_missed_calls_count().
  * @param[in] lc #LinphoneCore object.
  * @returns The number of missed calls.
- * @ingroup call_logs
 **/
-LINPHONE_PUBLIC	int linphone_core_get_missed_calls_count(LinphoneCore *lc);
+LINPHONE_PUBLIC int linphone_core_get_missed_calls_count(LinphoneCore *lc);
 
 /**
  * Reset the counter of missed calls.
  * @param[in] lc #LinphoneCore object.
- * @ingroup call_logs
 **/
-LINPHONE_PUBLIC	void linphone_core_reset_missed_calls_count(LinphoneCore *lc);
+LINPHONE_PUBLIC void linphone_core_reset_missed_calls_count(LinphoneCore *lc);
 
 /**
  * Remove a specific call log from call history list.
  * This function destroys the call log object. It must not be accessed anymore by the application after calling this function.
  * @param[in] lc #LinphoneCore object
  * @param[in] call_log #LinphoneCallLog object to remove.
- * @ingroup call_logs
 **/
-LINPHONE_PUBLIC	void linphone_core_remove_call_log(LinphoneCore *lc, LinphoneCallLog *call_log);
+LINPHONE_PUBLIC void linphone_core_remove_call_log(LinphoneCore *lc, LinphoneCallLog *call_log);
+
+/**
+ * @}
+**/
+
 
 /* video support */
 LINPHONE_PUBLIC bool_t linphone_core_video_supported(LinphoneCore *lc);
diff --git a/coreapi/private.h b/coreapi/private.h
index 136c8189bc..6ea57830e3 100644
--- a/coreapi/private.h
+++ b/coreapi/private.h
@@ -824,6 +824,7 @@ void _linphone_core_codec_config_write(LinphoneCore *lc);
 #ifndef NB_MAX_CALLS
 #define NB_MAX_CALLS	(10)
 #endif
+void call_logs_read_from_config_file(LinphoneCore *lc);
 void call_logs_write_to_config_file(LinphoneCore *lc);
 
 int linphone_core_get_edge_bw(LinphoneCore *lc);
-- 
GitLab