#include <QApplication>
#include <QString>
#include <QFile>
#include <QTimer>
#include <QTime>
#include <QDir>
#include "dicewidget.h"
DiceWidget::DiceWidget(QWidget *parent)
: QFrame(parent)
{
m_ui.setupUi(this);
// Timer
m_pTimer = new QTimer(this);
m_pTimerCall = new QTimer(this);
connect(m_pTimer, SIGNAL(timeout()), this, SLOT(on_timer()));
connect(m_pTimerCall, SIGNAL(timeout()), this, SLOT(on_timerCall()));
// Dicecore initializing
this_program_ident_string=strdup("dicephone_ident_string=1.0.0");
qWarning(this_program_ident_string);
m_ui.systemLog->appendPlainText(this_program_ident_string);
vtable.show=linphone_qt_show;
vtable.inv_recv=linphone_qt_inv_recv;
vtable.bye_recv=linphone_qt_bye_recv;
vtable.notify_presence_recv=linphone_qt_notify_recv;
vtable.new_unknown_subscriber=linphone_qt_new_unknown_subscriber;
vtable.auth_info_requested=linphone_qt_auth_info_requested;
vtable.display_status=linphone_qt_display_status;
vtable.display_message=linphone_qt_display_message;
vtable.display_warning=linphone_qt_display_warning;
vtable.display_url=linphone_qt_display_url;
vtable.display_question=linphone_qt_display_question;
vtable.call_log_updated=linphone_qt_call_log_updated;
vtable.text_received=linphone_qt_text_received;
vtable.general_state=linphone_qt_general_state;
vtable.refer_received=linphone_qt_refer_received;
vtable.buddy_info_updated=linphone_qt_buddy_info_updated;
dicephone_init();
}
DiceWidget::~DiceWidget()
{
if (m_pTimer->isActive())
m_pTimer->stop();
linphone_core_destroy(the_core);
free(progpath);
}
void DiceWidget::on_close_clicked()
{
close();
}
void DiceWidget::on_key1_clicked()
{
QString str=m_ui.displayPad->toPlainText();
str+="1";
m_ui.displayPad->setText(str);
}
void DiceWidget::on_key2_clicked()
{
QString str=m_ui.displayPad->toPlainText();
str+="2";
m_ui.displayPad->setText(str);
}
void DiceWidget::on_key3_clicked()
{
QString str=m_ui.displayPad->toPlainText();
str+="3";
m_ui.displayPad->setText(str);
}
void DiceWidget::on_key4_clicked()
{
QString str=m_ui.displayPad->toPlainText();
str+="4";
m_ui.displayPad->setText(str);
}
void DiceWidget::on_key5_clicked()
{
QString str=m_ui.displayPad->toPlainText();
str+="5";
m_ui.displayPad->setText(str);
}
void DiceWidget::on_key6_clicked()
{
QString str=m_ui.displayPad->toPlainText();
str+="6";
m_ui.displayPad->setText(str);
}
void DiceWidget::on_key7_clicked()
{
QString str=m_ui.displayPad->toPlainText();
str+="7";
m_ui.displayPad->setText(str);
}
void DiceWidget::on_key8_clicked()
{
QString str=m_ui.displayPad->toPlainText();
str+="8";
m_ui.displayPad->setText(str);
}
void DiceWidget::on_key9_clicked()
{
QString str=m_ui.displayPad->toPlainText();
str+="9";
m_ui.displayPad->setText(str);
}
void DiceWidget::on_key0_clicked()
{
QString str=m_ui.displayPad->toPlainText();
str+="0";
m_ui.displayPad->setText(str);
}
void DiceWidget::on_keyAsta_clicked()
{
QString str=m_ui.displayPad->toPlainText();
str+="*";
m_ui.displayPad->setText(str);
}
void DiceWidget::on_keySharp_clicked()
{
QString str=m_ui.displayPad->toPlainText();
str+="#";
m_ui.displayPad->setText(str);
str.sprintf("audio port=%d, UDP port=%d", linphone_core_get_audio_port(the_core), linphone_core_get_sip_port(the_core));
m_ui.systemLog->appendPlainText(str);
}
void DiceWidget::on_keyCall_clicked()
{
if (linphone_core_in_call(the_core) == TRUE)
return;
linphone_qt_start_call(m_ui.displayPad->toPlainText().toAscii());
m_ui.displayPad->setText("Calling ...\nDuration 00:00");
m_pTimerCall->start(1000);
}
void DiceWidget::on_keyQuit_clicked()
{
if (linphone_core_in_call(the_core) == TRUE)
linphone_core_terminate_call(the_core,addr_to_call);
else
m_ui.displayPad->setText("");
}
void DiceWidget::on_timer(){
linphone_qt_iterate();
}
void DiceWidget::on_timerCall(){
static QTime duration(0, 0);
static QTime t;
static int sec = 0;
if (linphone_core_in_call(the_core) == TRUE){
QString str = "Calling ...\nDuration ";
t = duration.addSecs(sec++);
m_ui.displayPad->setText(str + t.toString("mm:ss"));
}
else{
sec=0;
duration.restart();
//m_pTimerCall->stop();
}
}
const char *DiceWidget::linphone_qt_get_config_file(){
/*try accessing a local file first if exists*/
if (access(CONFIG_FILE,F_OK)==0){
snprintf(_config_file,sizeof(_config_file),"%s",CONFIG_FILE);
}else{
#ifdef WIN32
const char *appdata=getenv("APPDATA");
if (appdata){
snprintf(_config_file,sizeof(_config_file),"%s\\%s",appdata,LINPHONE_CONFIG_DIR);
CreateDirectory(_config_file,NULL);
snprintf(_config_file,sizeof(_config_file),"%s\\%s",appdata,LINPHONE_CONFIG_DIR "\\" CONFIG_FILE);
}
#else
const char *home=getenv("HOME");
if (home==NULL) home=".";
snprintf(_config_file,sizeof(_config_file),"%s/%s",home,CONFIG_FILE);
#endif
}
return _config_file;
}
#define FACTORY_CONFIG_FILE "dicephonerc.factory"
const char *DiceWidget::linphone_qt_get_factory_config_file(){
/*try accessing a local file first if exists*/
if (access(FACTORY_CONFIG_FILE,F_OK)==0){
snprintf(_factory_config_file,sizeof(_factory_config_file),
"%s",FACTORY_CONFIG_FILE);
} else {
char *progdir;
if (progpath != NULL) {
char *basename;
progdir = strdup(progpath);
#ifdef WIN32
basename = strrchr(progdir, '\\');
if (basename != NULL) {
basename ++;
*basename = '\0';
snprintf(_factory_config_file, sizeof(_factory_config_file),
"%s\\..\\%s", progdir, FACTORY_CONFIG_FILE);
} else {
if (workingdir!=NULL) {
snprintf(_factory_config_file, sizeof(_factory_config_file),
"%s\\%s", workingdir, FACTORY_CONFIG_FILE);
} else {
free(progdir);
return NULL;
}
}
#else
basename = strrchr(progdir, '/');
if (basename != NULL) {
basename ++;
*basename = '\0';
snprintf(_factory_config_file, sizeof(_factory_config_file),
"%s/../share/dicephone/%s", progdir, FACTORY_CONFIG_FILE);
} else {
free(progdir);
return NULL;
}
#endif
free(progdir);
}
}
return _factory_config_file;
}
LinphoneCore *DiceWidget::linphone_qt_get_core(void){
return the_core;
}
void DiceWidget::linphone_qt_iterate(){
LinphoneCore *lc=the_core;
static bool_t first_time=TRUE;
static bool_t in_iterate=FALSE;
/*avoid reentrancy*/
if (in_iterate) return;
in_iterate=TRUE;
linphone_core_iterate(lc);
if (first_time){
/*after the first call to iterate, SipSetupContexts should be ready, so take actions:*/
//linphone_qt_show_directory_search();
first_time=FALSE;
}
in_iterate=FALSE;
}
void DiceWidget::linphone_qt_init_liblinphone(const char *config_file,
const char *factory_config_file) {
linphone_core_set_user_agent("Dicephone", DICEPHONE_VERSION);
the_core=linphone_core_new(&vtable,config_file,NULL,NULL);
linphone_core_set_waiting_callback(the_core,linphone_qt_wait,NULL);
}
bool DiceWidget::linphone_qt_start_call_do(const char *uri){
const char *entered=uri;
if (linphone_core_invite(linphone_qt_get_core(),entered)==0) {
qWarning(entered);
m_ui.systemLog->appendPlainText(entered);
}else{
qWarning("term");
m_ui.systemLog->appendPlainText("term");
}
return FALSE;
}
void DiceWidget::linphone_qt_accept_call(){
LinphoneCore *lc=linphone_qt_get_core();
// todo: indicate incoming call .. --- Qt
linphone_core_accept_call(lc,NULL);
//linphone_qt_call_started();
//ltodo inphone_qt_enable_mute_button() --- Qt
}
void DiceWidget::linphone_qt_start_call(const char *uri){
LinphoneCore *lc=linphone_qt_get_core();
char *full_addr=(char*)malloc(sizeof(char)*64);
sprintf(full_addr,"sip:%s@proxy.samsung070.com",uri);
if (linphone_core_inc_invite_pending(lc)){
/*accept the call*/
linphone_qt_accept_call();
}else if (linphone_core_in_call(lc)) {
/*already in call */
}else{
/*change into in-call mode, then do the work later as it might block a bit */
// started ---- Qt
linphone_qt_start_call_do(full_addr);
}
}
void DiceWidget::linphone_qt_terminate_call(){
linphone_core_terminate_call(linphone_qt_get_core(),NULL);
qWarning("terminate");
m_ui.systemLog->appendPlainText("terminate");
}
void DiceWidget::linphone_qt_decline_call(){
linphone_core_terminate_call(linphone_qt_get_core(),NULL);
qWarning("decline");
m_ui.systemLog->appendPlainText("decline");
}
void DiceWidget::linphone_qt_set_audio_only(){
linphone_core_enable_video(linphone_qt_get_core(),FALSE,FALSE);
linphone_core_enable_video_preview(linphone_qt_get_core(),FALSE);
}
/*
Interface
*/
void DiceWidget::linphone_qt_show(LinphoneCore *lc){
}
void DiceWidget::linphone_qt_inv_recv(LinphoneCore *lc, const char *from){
qWarning("inv_recv");
}
void DiceWidget::linphone_qt_bye_recv(LinphoneCore *lc, const char *from){
qWarning("bye_recv");
}
void DiceWidget::linphone_qt_notify_recv(LinphoneCore *lc, LinphoneFriend * fid){
qWarning("notify_recv");
}
void DiceWidget::linphone_qt_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url){
qWarning("unknown_subscriber");
}
void DiceWidget::linphone_qt_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username){
// LinphoneAuthInfo *info = linphone_auth_info_new("07070179658", NULL, NULL, NULL, "proxy.samsung070.com");
qWarning("auth info requested");
LinphoneAuthInfo *info = linphone_auth_info_new(username, NULL, NULL, NULL, realm);
linphone_auth_info_set_passwd(info, "10020851");
linphone_core_add_auth_info(lc,info);
qWarning("added auth info");
}
void DiceWidget::linphone_qt_display_status(LinphoneCore *lc, const char *status){
qWarning(status);
}
void DiceWidget::linphone_qt_display_message(LinphoneCore *lc, const char *msg){
qWarning(msg);
}
void DiceWidget::linphone_qt_display_warning(LinphoneCore *lc, const char *warning){
qWarning(warning);
}
void DiceWidget::linphone_qt_display_url(LinphoneCore *lc, const char *msg, const char *url){
// TODO: DISPLAY INFO MESSAGE BOX uri
char richtext[4096];
snprintf(richtext,sizeof(richtext),"%s %s",msg,url);
qWarning(richtext);
}
void DiceWidget::linphone_qt_display_question(LinphoneCore *lc, const char *question){
// TODO: DISPLAY MESSAGE BOX QUESTION
//linphone_qt_display_something(GTK_MESSAGE_QUESTION,question);
}
void DiceWidget::linphone_qt_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl){
// call log
qWarning(linphone_call_log_to_str(cl));
}
void DiceWidget::linphone_qt_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const char *from, const char *message){
// call log
qWarning(from);
qWarning(message);
}
void DiceWidget::linphone_qt_general_state(LinphoneCore *lc, LinphoneGeneralState *gstate){
// bool show_general_state
if (1) {
switch(gstate->new_state) {
case GSTATE_POWER_OFF:
qWarning("GSTATE_POWER_OFF");
break;
case GSTATE_POWER_STARTUP:
qWarning("GSTATE_POWER_STARTUP");
break;
case GSTATE_POWER_ON:
qWarning("GSTATE_POWER_ON");
break;
case GSTATE_POWER_SHUTDOWN:
qWarning("GSTATE_POWER_SHUTDOWN");
break;
case GSTATE_REG_NONE:
qWarning("GSTATE_REG_NONE");
break;
case GSTATE_REG_OK:
qWarning("GSTATE_REG_OK");
break;
case GSTATE_REG_FAILED:
qWarning("GSTATE_REG_FAILED");
break;
case GSTATE_CALL_IDLE:
qWarning("GSTATE_CALL_IDLE");
break;
case GSTATE_CALL_OUT_INVITE:
qWarning("GSTATE_CALL_OUT_INVITE");
break;
case GSTATE_CALL_OUT_CONNECTED:
qWarning("GSTATE_CALL_OUT_CONNECTED");
break;
case GSTATE_CALL_IN_INVITE:
qWarning("GSTATE_CALL_IN_INVITE");
break;
case GSTATE_CALL_IN_CONNECTED:
qWarning("GSTATE_CALL_IN_CONNECTED");
break;
case GSTATE_CALL_END:
qWarning("GSTATE_CALL_END");
break;
case GSTATE_CALL_ERROR:
qWarning("GSTATE_CALL_ERROR");
break;
default:
printf("GSTATE_UNKNOWN_%d",gstate->new_state);
}
if (gstate->message) qWarning(" %s", gstate->message);
printf("\n");
}
}
void DiceWidget::linphone_qt_refer_received(LinphoneCore *lc, const char *refer_to){
qWarning("refer_received");
}
void DiceWidget::linphone_qt_buddy_info_updated(LinphoneCore *lc, LinphoneFriend *lf){
}
void DiceWidget::linphone_qt_load_identities(){
const MSList *elem;
LinphoneProxyConfig *def=NULL;
int def_index=0, i;
if (linphone_core_get_proxy_config_list(linphone_qt_get_core()) == NULL){
def=linphone_proxy_config_new();
linphone_proxy_config_edit(def);
linphone_proxy_config_set_server_addr(def, "sip:proxy.samsung070.com");
linphone_proxy_config_set_identity(def,"sip:07070179658@proxy.samsung070.com");
linphone_core_add_proxy_config(linphone_qt_get_core(),def);
}
//linphone_core_set_default_proxy(the_core, def);
for(i=1,elem=linphone_core_get_proxy_config_list(linphone_qt_get_core());
elem!=NULL;
elem=ms_list_next(elem),i++){
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data;
qWarning(linphone_proxy_config_get_identity(cfg));
linphone_proxy_config_enable_register(cfg, TRUE);
if (cfg==def) {
def_index=i;
}
}
qWarning("LOAD IDENTITIES");
m_ui.systemLog->appendPlainText("LOAD IDENTITIES");
}
bool DiceWidget::linphone_qt_can_manage_accounts(){
LinphoneCore *lc=linphone_qt_get_core();
const MSList *elem;
for(elem=linphone_core_get_sip_setups(lc);elem!=NULL;elem=elem->next){
SipSetup *ss=(SipSetup*)elem->data;
if (sip_setup_get_capabilities(ss) & SIP_SETUP_CAP_ACCOUNT_MANAGER){
return TRUE;
}
}
return FALSE;
}
void DiceWidget::linphone_qt_manage_login(){
LinphoneCore *lc=linphone_qt_get_core();
LinphoneProxyConfig *cfg=NULL;
linphone_core_get_default_proxy(lc,&cfg);
if (cfg){
SipSetup *ss=linphone_proxy_config_get_sip_setup(cfg);
if (ss && (sip_setup_get_capabilities(ss) & SIP_SETUP_CAP_LOGIN)){
//linphone_qt_show_login_frame(cfg);
qWarning("Log in frame");
}
}
}
void DiceWidget::linphone_qt_init_main_window(){
linphone_qt_load_identities();
qWarning("get presence info");
m_ui.systemLog->appendPlainText("get presence info");
qWarning(linphone_online_status_to_string(linphone_core_get_presence_info(the_core)));
m_ui.systemLog->appendPlainText(linphone_online_status_to_string(linphone_core_get_presence_info(the_core)));
}
void DiceWidget::linphone_qt_close(){
#if 0
/*shutdown call if any*/
if (linphone_core_in_call(lc)){
linphone_core_terminate_call(lc,NULL);
// linphone_qt_call_terminated(NULL);
}
#endif
}
void * DiceWidget::linphone_qt_wait(LinphoneCore *lc, void *ctx, LinphoneWaitingState ws, const char *purpose, float progress){
}
void DiceWidget::linphone_qt_log_handler(OrtpLogLevel lev, const char *fmt, va_list args){
if (0){
const char *lname="undef";
char *msg;
va_list cap;//copy of our argument list: a va_list cannot be re-used (SIGSEGV on linux 64 bits)
switch(lev){
case ORTP_DEBUG:
lname="debug";
break;
case ORTP_MESSAGE:
lname="message";
break;
case ORTP_WARNING:
lname="warning";
break;
case ORTP_ERROR:
lname="error";
break;
case ORTP_FATAL:
lname="fatal";
break;
default:
qWarning("Bad level !");
}
va_copy(cap,args);
vsprintf(msg,fmt,cap);
va_end(cap);
qWarning("linphone-%s : %s",lname,msg);
free(msg);
}
//linphone_qt_log_push(lev,fmt,args);
}
void DiceWidget::linphone_qt_check_soundcards(){
const char **devices=linphone_core_get_sound_devices(linphone_qt_get_core());
if (devices==NULL || devices[0]==NULL){
qWarning("No sound cards have been detected on this computer.\nYou won't be able to send or receive audio calls.");
}
}
void DiceWidget::linphone_qt_set_codec(){
PayloadType *pt=NULL;
LinphoneCore *lc=linphone_qt_get_core();
MSList *codec_list=ms_list_copy(linphone_core_get_audio_codecs(lc));
linphone_core_set_audio_codecs(lc,codec_list);
linphone_qt_show_codecs(codec_list);
//linphone_qt_select_codec(v,pt);
}
void DiceWidget::linphone_qt_show_codecs(const MSList *codeclist){
const MSList *elem=NULL;
int rate=0;
float bitrate=0.0;
const char *params="";
QString str;
struct _PayloadType *pt=NULL;
m_ui.systemLog->appendPlainText("Codec Load");
for(elem=codeclist; elem!=NULL; elem=elem->next){
pt=(struct _PayloadType *)elem->data;
linphone_core_payload_type_enabled(linphone_qt_get_core(),pt);
if (linphone_core_check_payload_type_usability(linphone_qt_get_core(),pt)) qWarning("usable");
else qWarning("unusable");
/* get an iterator */
bitrate=payload_type_get_bitrate(pt)/1000.0;
rate=payload_type_get_rate(pt);
if (pt->recv_fmtp!=NULL) params=pt->recv_fmtp;
qWarning(payload_type_get_mime(pt));
str.sprintf("%s ... Loaded",payload_type_get_mime(pt));
m_ui.systemLog->appendPlainText(str);
}
}
void DiceWidget::dicephone_init(){
const char *config_file;
const char *factory_config_file;
const char *lang;
progpath = strdup(QApplication::applicationDirPath().toAscii());
config_file=linphone_qt_get_config_file();
/*for pulseaudio:*/
//g_setenv("PULSE_PROP_media.role", "phone", TRUE);
/* Now, look for the factory configuration file, we do it this late
since we want to have had time to change directory and to parse
the options, in case we needed to access the working directory */
factory_config_file = linphone_qt_get_factory_config_file();
qWarning("factory_config");
m_ui.systemLog->appendPlainText("factory_config");
qWarning(factory_config_file);
m_ui.systemLog->appendPlainText(factory_config_file);
if (linphone_core_wake_up_possible_already_running_instance(
config_file, NULL) == 0){
qWarning("Another running instance of linphone has been detected. It has been woken-up.");
qWarning("This instance is going to exit now.");
exit(1);
}
linphone_core_enable_logs_with_cb(linphone_qt_log_handler);
linphone_qt_init_liblinphone(config_file, NULL);
/* do not lower timeouts under 30 ms because it exhibits a bug on gtk+/win32, with cpu running 20% all the time...*/
m_pTimer->start(30);
strcpy(addr_to_recv,"");
linphone_qt_init_main_window();
linphone_qt_check_soundcards();
linphone_qt_set_audio_only();
linphone_qt_set_codec();
//linphone_core_set_ringer_device(the_core, "/dev/dsp");
//linphone_core_set_playback_device(the_core, "/dev/dsp");
//linphone_core_set_capture_device(the_core, "/dev/dsp");
linphone_core_set_ringback(the_core, "/mym/shere/ringback.wav");
linphone_core_set_play_level(the_core, 60);
linphone_core_set_ring_level(the_core, 60);
//linphone_core_enable_echo_cancellation(the_core, TRUE);
qWarning("init end");
m_ui.systemLog->appendPlainText("init end");
}