/*
linphone
Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org)
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 "sipsetup.h"
#include "lpconfig.h"
#include "private.h"
#include <ortp/telephonyevents.h>
#include <ortp/zrtp.h>
#include "mediastreamer2/mediastream.h"
#include "mediastreamer2/mseventqueue.h"
#include "mediastreamer2/msvolume.h"
#include "mediastreamer2/msequalizer.h"
#include "mediastreamer2/dtmfgen.h"
#ifdef INET6
#ifndef WIN32
#include <netdb.h>
#endif
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/*#define UNSTANDART_GSM_11K 1*/
#define ROOT_CA_FILE PACKAGE_DATA_DIR "/linphone/rootca.pem"
static const char *liblinphone_version=LIBLINPHONE_VERSION;
static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t curtime);
static void linphone_core_run_hooks(LinphoneCore *lc);
static void linphone_core_free_hooks(LinphoneCore *lc);
#include "enum.h"
const char *linphone_core_get_nat_address_resolved(LinphoneCore *lc);
void linphone_core_get_local_ip(LinphoneCore *lc, const char *dest, char *result);
static void toggle_video_preview(LinphoneCore *lc, bool_t val);
/* relative path where is stored local ring*/
#define LOCAL_RING "rings/oldphone.wav"
/* same for remote ring (ringback)*/
#define REMOTE_RING "ringback.wav"
#define HOLD_MUSIC "rings/toy-mono.wav"
extern SalCallbacks linphone_sal_callbacks;
void lc_callback_obj_init(LCCallbackObj *obj,LinphoneCoreCbFunc func,void* ud)
{
obj->_func=func;
obj->_user_data=ud;
}
int lc_callback_obj_invoke(LCCallbackObj *obj, LinphoneCore *lc){
if (obj->_func!=NULL) obj->_func(lc,obj->_user_data);
return 0;
}
/*prevent a gcc bug with %c*/
static size_t my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm){
#if !defined(_WIN32_WCE)
return strftime(s, max, fmt, tm);
#else
return 0;
/*FIXME*/
#endif /*_WIN32_WCE*/
}
static void set_call_log_date(LinphoneCallLog *cl, const struct tm *loctime){
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);
struct tm loctime;
cl->dir=call->dir;
#ifdef WIN32
#if !defined(_WIN32_WCE)
loctime=*localtime(&call->start_time);
/*FIXME*/
#endif /*_WIN32_WCE*/
#else
localtime_r(&call->start_time,&loctime);
#endif
set_call_log_date(cl,&loctime);
cl->from=from;
cl->to=to;
cl->status=LinphoneCallAborted; /*default status*/
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_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);
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);
}
for(;i<lc->max_call_logs;++i){
snprintf(logsection,sizeof(logsection),"call_log_%i",i);
lp_config_clean_section(cfg,logsection);
}
}
static void call_logs_read_from_config_file(LinphoneCore *lc){
char logsection[32];
int i;
const char *tmp;
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);
tmp=lp_config_get_string(cfg,logsection,"start_date",NULL);
if (tmp) strncpy(cl->start_date,tmp,sizeof(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);
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;
}
void linphone_call_log_set_user_pointer(LinphoneCallLog *cl, void *up){
cl->user_pointer=up;
}
void *linphone_call_log_get_user_pointer(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;
}
/** @} */
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);
ms_free(cl);
}
/**
* Returns TRUE if the LinphoneCall asked to autoanswer
*
**/
bool_t linphone_call_asked_to_autoanswer(LinphoneCall *call){
//return TRUE if the uni
- 1
- 2
- 3
- 4
- 5
- 6
前往页