diff --git a/astylerc b/astylerc index 0170fbdc9431c1f5875bf75231dd88f8c692b06c..460124f66d7a1f71a6c4d0a168f9502e4755a059 100644 --- a/astylerc +++ b/astylerc @@ -12,4 +12,5 @@ indent-switches # Indent 'switch' blocks so that the 'case X:' statement break-blocks # Pad empty lines around header blocks (e.g. 'if', 'while'...). brackets=linux unpad=paren +formatted -d diff --git a/hudson-sflphone-script.sh b/hudson-sflphone-script.sh new file mode 100755 index 0000000000000000000000000000000000000000..392389076de5062cfe9b59e2b15664bbf566044f --- /dev/null +++ b/hudson-sflphone-script.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# +# Script used by Hudson continious integration server to build SFLphone +# +# Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> + +set -x + +# Compile the daemon +pushd sflphone-common +./autogen.sh + Compile pjproject first +pushd libs/pjproject +./autogen.sh +./configure +make && make dep +popd +./configure --prefix=/usr +make +popd + +# Run the unit tests for the daemon +pushd sflphone-common/test +make check +# if at least one test failed, exit +./test || exit 1 +popd + +# Compile the client +pushd sflphone-client-gnome +./autogen.sh +./configure --prefix=/usr +make +popd + +# SUCCESS +exit 0 diff --git a/sflphone-client-gnome/INSTALL b/sflphone-client-gnome/INSTALL index 2550dab75261145b56f3d223673e00bef2aa78df..7d1c323beae76333f523f6df31c47a87f5597edb 100644 --- a/sflphone-client-gnome/INSTALL +++ b/sflphone-client-gnome/INSTALL @@ -4,8 +4,10 @@ Installation Instructions Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. - This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. Basic Installation ================== @@ -13,7 +15,11 @@ Basic Installation Briefly, the shell commands `./configure; make; make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the `README' file for -instructions specific to this package. +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses @@ -42,7 +48,7 @@ may remove or edit it. you want to change it or regenerate `configure' using a newer version of `autoconf'. -The simplest way to compile this package is: + The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. @@ -53,12 +59,22 @@ The simplest way to compile this package is: 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with - the package. + the package, generally using the just-built uninstalled binaries. 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is @@ -67,8 +83,15 @@ The simplest way to compile this package is: all sorts of other programs in order to regenerate files that came with the distribution. - 6. Often, you can also type `make uninstall' to remove the installed - files again. + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. Compilers and Options ===================== @@ -93,7 +116,8 @@ same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. With a non-GNU `make', it is safer to compile the package for one architecture at a time in the source code directory. After you have @@ -120,7 +144,8 @@ Installation Names By default, `make install' installs the package's commands under `/usr/local/bin', include files under `/usr/local/include', etc. You can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you @@ -131,15 +156,46 @@ Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=DIR' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. -Optional Features -================= - Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE @@ -152,6 +208,13 @@ find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + Particular systems ================== @@ -288,7 +351,7 @@ operates. `configure' can determine that directory automatically. `--prefix=DIR' - Use DIR as the installation prefix. *Note Installation Names:: + Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. diff --git a/sflphone-client-gnome/Makefile.am b/sflphone-client-gnome/Makefile.am index 5a51abcf586b1c258dfe47203f32c81f7ca21b17..e738c4d1604c0fd7a8c550433693ebb1a1d0ba4e 100644 --- a/sflphone-client-gnome/Makefile.am +++ b/sflphone-client-gnome/Makefile.am @@ -1,21 +1,20 @@ SUBDIRS = src pixmaps webkit tests man po doc +CFLAGS=-Wall -Werror -Wextra + ACLOCAL_AMFLAGS = -I m4 GCONFTOOL=gconftool-2 GNOME_DOC=gnome-doc-utils.make -log4crc_DATA = log4crc -log4crcdir = $(datadir)/sflphone - uidir=$(datadir)/sflphone/ui ui_DATA=src/ui.xml schemadir = @GCONF_SCHEMA_FILE_DIR@ schema_DATA = sflphone-client-gnome.schemas -EXTRA_DIST = $(log4crc_DATA) sflphone.desktop.in $(GNOME_DOC) m4 $(UI_DATA) $(schema_DATA) +EXTRA_DIST = sflphone.desktop.in $(GNOME_DOC) m4 $(UI_DATA) $(schema_DATA) appsdir = $(datadir)/applications apps_in_files = sflphone.desktop.in apps_DATA = $(apps_in_files:.desktop.in=.desktop) diff --git a/sflphone-client-gnome/configure.ac b/sflphone-client-gnome/configure.ac index f55e2b530893b7d95e6b383b1fdbf3dc6aa3caed..c5f2be88f180d1ed8c1907e5388786c5442851c3 100644 --- a/sflphone-client-gnome/configure.ac +++ b/sflphone-client-gnome/configure.ac @@ -24,7 +24,7 @@ AC_ARG_WITH(debug, if test "x$with_debug" = "xfull" -o "x$with_debug" = "xyes"; then CFLAGS="-g -O0 -DDEBUG -Wall -Wextra" else - CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wall -Wextra" fi AC_PROG_CC @@ -35,12 +35,6 @@ AC_PROG_LIBTOOL dnl GCONF utilities AM_GCONF_SOURCE_2 -dnl Check for log4c -AC_CHECK_HEADERS(log4c.h, have_log4c=true, have_log4c=false) -if ! $have_log4c; then - AC_MSG_ERROR(Please install the log4c library) -fi - dnl uninstalled gsr ui dir AC_DEFINE_UNQUOTED(SFLPHONE_UIDIR_UNINSTALLED, "`pwd`/src/", [path to uninstalled SFLphone UI dir]) diff --git a/sflphone-client-gnome/log4crc b/sflphone-client-gnome/log4crc deleted file mode 100644 index e108c9378b0e99e095389c63d029db54a1791290..0000000000000000000000000000000000000000 --- a/sflphone-client-gnome/log4crc +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<!DOCTYPE log4c SYSTEM ""> - -<log4c version="1.2.1"> - <config> - <bufsize>0</bufsize> - <debug level="2"/> - <nocleanup>0</nocleanup> - <reread>1</reread> - </config> - - <rollingpolicy name="rollingpolicy" type="sizewin" maxsize="1024" maxnum="10" /> - <appender name="rollingfileappender" type="rollingfile" logdir="." prefix="prefix" layout="dated" rollingpolicy="rollingpolicy" /> - - <appender name="stdout" type="stream" layout="basic"/> - <appender name="stderr" type="stream" layout="dated"/> - <appender name="syslog" type="syslog" layout="basic"/> - - <layout name="basic" type="basic"/> - <layout name="dated" type="dated"/> - - <category name="root" priority="warning"/> - <category name="org.sflphone.gtk" priority="warning" appender="stdout" /> -</log4c> diff --git a/sflphone-client-gnome/src/Makefile.am b/sflphone-client-gnome/src/Makefile.am index 0cce83bab2686c8cc008d352e779ea8953ef3c03..06e6b6ac5bb5c31b4e4005540b91ac61481e1175 100644 --- a/sflphone-client-gnome/src/Makefile.am +++ b/sflphone-client-gnome/src/Makefile.am @@ -5,14 +5,14 @@ bin_PROGRAMS = sflphone-client-gnome SUBDIRS = config contacts dbus widget icons NOFIFY_LIBS = -lnotify -LOG4C = -llog4c - +X11_LIBS = -lX11 SFLPHONEGTK_LIBS=./contacts/libcontacts.la ./config/libconfig.la ./dbus/libdbus.la ./widget/libwidget.la ./icons/libicons.la sflphone_client_gnome_SOURCES = \ main.c \ errors.c \ + logger.c \ uimanager.c \ sflnotify.c \ mainwindow.c \ @@ -32,9 +32,9 @@ sflphone_client_gnome_SOURCES = \ noinst_HEADERS = actions.h sflnotify.h mainwindow.h dialpad.h codeclist.h \ reqaccount.h errors.h sflphone_const.h uimanager.h \ accountlist.h sliders.h statusicon.h callable_obj.h conference_obj.h \ - shortcuts.h eel-gconf-extensions.h + shortcuts.h eel-gconf-extensions.h logger.h -sflphone_client_gnome_LDADD = $(DEPS_LIBS) $(NOTIFY_LIBS) $(SFLPHONEGTK_LIBS) $(LIBSEXY_LIBS) $(LOG4C) +sflphone_client_gnome_LDADD = $(DEPS_LIBS) $(NOTIFY_LIBS) $(SFLPHONEGTK_LIBS) $(LIBSEXY_LIBS) $(X11_LIBS) # add symbolic link install-exec-local: diff --git a/sflphone-client-gnome/src/accountlist.c b/sflphone-client-gnome/src/accountlist.c index 52109a17b133cf5aca14fba2e14ccf2bd2f7e562..d73f3450c9f9d4cc926128daaf7133fc5fe07214 100644 --- a/sflphone-client-gnome/src/accountlist.c +++ b/sflphone-client-gnome/src/accountlist.c @@ -39,6 +39,9 @@ GQueue * accountQueue; gint is_accountID_struct (gconstpointer a, gconstpointer b) { + if (!a || !b) + return 1; + account_t * c = (account_t*) a; if (strcmp (c->accountID, (gchar*) b) == 0) { @@ -247,11 +250,12 @@ account_list_get_registered_accounts (void) unsigned int i; for (i=0; i<account_list_get_size(); i++) { + if (account_list_get_nth (i) -> state == (ACCOUNT_STATE_REGISTERED)) res ++; } - DEBUG (" %d registered accounts" , res); + DEBUG ("Account: %d registered accounts" , res); return res; } @@ -356,7 +360,9 @@ gboolean current_account_has_mailbox (void) current = account_list_get_current (); if (current) { - if (g_strcasecmp (g_hash_table_lookup (current->properties, ACCOUNT_MAILBOX), "") != 0) + gchar * account_mailbox = g_hash_table_lookup (current->properties, ACCOUNT_MAILBOX); + + if (account_mailbox != NULL && g_strcasecmp (account_mailbox, "") != 0) return TRUE; } diff --git a/sflphone-client-gnome/src/accountlist.h b/sflphone-client-gnome/src/accountlist.h index d1f40bc4186ee9896ab6a5ae4c35fb3227896a40..9aa8bb361a0b8b2383e9f9a3b2b34c4483d4e3db 100644 --- a/sflphone-client-gnome/src/accountlist.h +++ b/sflphone-client-gnome/src/accountlist.h @@ -205,7 +205,7 @@ gchar * account_list_get_ordered_list (void); guint account_list_get_position (account_t *account); -gboolean account_list_current_account_has_mailbox (void); +gboolean current_account_has_mailbox (void); guint current_account_get_message_number (void); diff --git a/sflphone-client-gnome/src/actions.c b/sflphone-client-gnome/src/actions.c index 45275b2ce611b98efd679d0c7df374d03c367a01..a787748a8132021f57d39209a0230bcd2adb4b13 100644 --- a/sflphone-client-gnome/src/actions.c +++ b/sflphone-client-gnome/src/actions.c @@ -66,6 +66,8 @@ sflphone_notify_voice_mail (const gchar* accountID , guint count) id = g_strdup (accountID); current_id = account_list_get_current_id (); + DEBUG ("sflphone_notify_voice_mail begin"); + if (g_strcasecmp (id, current_id) != 0 || account_list_get_size() == 0) return; @@ -78,6 +80,8 @@ sflphone_notify_voice_mail (const gchar* accountID , guint count) if (current) notify_voice_mails (count, current); + + DEBUG ("sflphone_notify_voice_mail end"); } /* @@ -120,6 +124,8 @@ status_bar_display_account () statusbar_pop_message (__MSG_ACCOUNT_DEFAULT); + DEBUG ("status_bar_display_account begin"); + acc = account_list_get_current (); if (acc) { @@ -133,8 +139,10 @@ status_bar_display_account () msg = g_markup_printf_escaped (_ ("No registered accounts")); } - statusbar_push_message (msg , __MSG_ACCOUNT_DEFAULT); + statusbar_push_message (msg, NULL, __MSG_ACCOUNT_DEFAULT); g_free (msg); + + DEBUG ("status_bar_display_account_end"); } @@ -183,6 +191,8 @@ sflphone_ringing (callable_obj_t * c) void sflphone_hung_up (callable_obj_t * c) { + DEBUG ("SFLphone: Hung up"); + calllist_remove (current_calls, c->_callID); calltree_remove_call (current_calls, c, NULL); c->_state = CALL_STATE_DIALING; @@ -195,12 +205,7 @@ sflphone_hung_up (callable_obj_t * c) #if GTK_CHECK_VERSION(2,10,0) status_tray_icon_blink (FALSE); #endif -} - -static hashtable_free (gpointer key, gpointer value, gpointer user_data) -{ - g_free (key); - g_free (value); + calltree_update_clock(); } /** Internal to actions: Fill account list */ @@ -211,7 +216,6 @@ void sflphone_fill_account_list (void) gchar** accountID; unsigned int i; int count; - GQueue *codeclist; DEBUG ("SFLphone: Fill account list"); @@ -222,11 +226,11 @@ void sflphone_fill_account_list (void) array = (gchar **) dbus_account_list(); if (array) { + for (accountID = array; *accountID; accountID++) { account_t * a = g_new0 (account_t,1); a->accountID = g_strdup (*accountID); a->credential_information = NULL; - // TODO Clean codec list QUEUE account_list_add (a); } @@ -355,6 +359,8 @@ sflphone_hang_up() callable_obj_t * selectedCall = calltab_get_selected_call (current_calls); conference_obj_t * selectedConf = calltab_get_selected_conf (active_calltree); + DEBUG ("SFLphone: Hang up"); + if (selectedCall) { switch (selectedCall->_state) { case CALL_STATE_DIALING: @@ -402,6 +408,10 @@ sflphone_hang_up() } calltree_update_call (history, selectedCall, NULL); + + stop_call_clock (selectedCall); + + calltree_update_clock(); } @@ -505,17 +515,6 @@ sflphone_off_hold () dbus_unhold_conference (selectedConf); } - - /* - if(dbus_get_is_recording(selectedCall)) - { - DEBUG("Currently recording!"); - } - else - { - DEBUG("Not recording currently"); - } - */ } @@ -589,7 +588,7 @@ sflphone_unset_transfert() void sflphone_display_transfer_status (const gchar* message) { - statusbar_push_message (message , __MSG_ACCOUNT_DEFAULT); + statusbar_push_message (message , NULL, __MSG_ACCOUNT_DEFAULT); } void @@ -608,7 +607,7 @@ sflphone_incoming_call (callable_obj_t * c) if (_is_direct_call (c)) { msg = g_markup_printf_escaped (_ ("Direct SIP call")); statusbar_pop_message (__MSG_ACCOUNT_DEFAULT); - statusbar_push_message (msg , __MSG_ACCOUNT_DEFAULT); + statusbar_push_message (msg , NULL, __MSG_ACCOUNT_DEFAULT); g_free (msg); } } @@ -695,7 +694,7 @@ sflphone_new_call() callable_obj_t * current_selected_call; gchar *peer_name, *peer_number; - DEBUG ("sflphone_new_call"); + DEBUG ("Actions: Sflphone new call"); current_selected_call = calltab_get_selected_call (current_calls); @@ -865,7 +864,7 @@ static int _place_registered_call (callable_obj_t * c) account_t * current = NULL; if (c == NULL) { - DEBUG ("callable_obj_t is NULL in _place_registered_call"); + DEBUG ("Actions: Callable_obj_t is NULL in _place_registered_call"); return -1; } @@ -884,25 +883,32 @@ static int _place_registered_call (callable_obj_t * c) } if (account_list_get_by_state (ACCOUNT_STATE_REGISTERED) == NULL) { + DEBUG ("Actions: No registered account, cannot make a call"); notify_no_registered_accounts(); sflphone_fail (c); return -1; } + DEBUG ("Actions: Get account for this call"); + if (g_strcasecmp (c->_accountID, "") != 0) { + DEBUG ("Actions: Account %s already set for this call", c->_accountID); current = account_list_get_by_id (c->_accountID); } else { + DEBUG ("Actions: No account set for this call, use first of the list"); current = account_list_get_current(); } if (current == NULL) { - DEBUG ("Unexpected condition: account_t is NULL in %s at %d for accountID %s", __FILE__, __LINE__, c->_accountID); + DEBUG ("Actions: Unexpected condition: account_t is NULL in %s at %d for accountID %s", __FILE__, __LINE__, c->_accountID); return -1; } if (g_strcasecmp (g_hash_table_lookup (current->properties, "Status"),"REGISTERED") ==0) { /* The call is made with the current account */ - c->_accountID = current->accountID; + // free memory for previous account id and get a new one + g_free (c->_accountID); + c->_accountID = g_strdup (current->accountID); dbus_place_call (c); } else { /* Place the call with the first registered account @@ -910,7 +916,8 @@ static int _place_registered_call (callable_obj_t * c) * If we are here, we can be sure that there is at least one. */ current = account_list_get_by_state (ACCOUNT_STATE_REGISTERED); - c->_accountID = current->accountID; + g_free (c->_accountID); + c->_accountID = g_strdup (current->accountID); dbus_place_call (c); notify_current_account (current); } @@ -925,17 +932,17 @@ sflphone_place_call (callable_obj_t * c) { gchar *msg = ""; - DEBUG ("Placing call with %s @ %s and accountid %s", c->_peer_name, c->_peer_number, c->_accountID); + DEBUG ("Actions: Placing call with %s @ %s and accountid %s", c->_peer_name, c->_peer_number, c->_accountID); if (c == NULL) { - DEBUG ("Unexpected condition: callable_obj_t is null in %s at %d", __FILE__, __LINE__); + DEBUG ("Actions: Unexpected condition: callable_obj_t is null in %s at %d", __FILE__, __LINE__); return; } if (_is_direct_call (c)) { msg = g_markup_printf_escaped (_ ("Direct SIP call")); statusbar_pop_message (__MSG_ACCOUNT_DEFAULT); - statusbar_push_message (msg , __MSG_ACCOUNT_DEFAULT); + statusbar_push_message (msg , NULL, __MSG_ACCOUNT_DEFAULT); g_free (msg); if (_place_direct_call (c) < 0) { @@ -1045,6 +1052,7 @@ sflphone_rec_call() conference_obj_t * selectedConf = calltab_get_selected_conf (current_calls); if (selectedCall) { + DEBUG ("SFLphone: Set record for selected call"); dbus_set_record (selectedCall->_callID); switch (selectedCall->_state) { @@ -1059,14 +1067,15 @@ sflphone_rec_call() break; } } else if (selectedConf) { + DEBUG ("SFLphone: Set record for selected conf"); dbus_set_record (selectedConf->_confID); switch (selectedConf->_state) { case CONFERENCE_STATE_ACTIVE_ATACHED: - selectedCall->_state = CONFERENCE_STATE_RECORD; + selectedConf->_state = CONFERENCE_STATE_RECORD; break; case CONFERENCE_STATE_RECORD: - selectedCall->_state = CONFERENCE_STATE_ACTIVE_ATACHED; + selectedConf->_state = CONFERENCE_STATE_ACTIVE_ATACHED; break; default: WARN ("Should not happen in sflphone_off_hold ()!"); @@ -1076,9 +1085,6 @@ sflphone_rec_call() calltree_update_call (current_calls, selectedCall, NULL); update_actions(); - - // gchar* codname = sflphone_get_current_codec_name(); - // DEBUG("sflphone_get_current_codec_name: %s",codname); } void sflphone_fill_codec_list () @@ -1087,7 +1093,6 @@ void sflphone_fill_codec_list () guint account_list_size; guint i; account_t *current = NULL; - gchar** codecs = NULL; DEBUG ("SFLphone: Fill codec list"); @@ -1101,23 +1106,13 @@ void sflphone_fill_codec_list () } } - /* - if (codec_list_get_size() == 0) { - - // Error message - ERROR ("No audio codecs found"); - dbus_unregister(getpid()); - exit(0); - }*/ } void sflphone_fill_codec_list_per_account (account_t **account) { gchar **order; - gchar** details; gchar** pl; - gchar *accountID; GQueue *codeclist; gboolean active = FALSE; @@ -1237,10 +1232,11 @@ void sflphone_fill_history (void) { GHashTable *entries; GHashTableIter iter; - gpointer key, key_to_min, value; + gpointer key, value; + gpointer key_to_min = NULL; callable_obj_t *history_entry; - - int timestamp, min_timestamp; + int timestamp = 0; + int min_timestamp = 0; gboolean is_first; @@ -1417,7 +1413,7 @@ sflphone_confirm_go_clear (callable_obj_t * c) void sflphone_call_state_changed (callable_obj_t * c, const gchar * description, const guint code) { - DEBUG ("sflphone_call_state_changed"); + DEBUG ("SFLPhone: sflphone_call_state_changed"); if (c == NULL) { DEBUG ("Panic callable obj is NULL in %s at %d", __FILE__, __LINE__); @@ -1426,6 +1422,7 @@ sflphone_call_state_changed (callable_obj_t * c, const gchar * description, cons //DEBUG("sflphone_call_state_changed"); c->_state_code_description = g_strdup (description); c->_state_code = code; + DEBUG ("SFLPhone: state code %d", c->_state_code); } calltree_update_call (current_calls, c, NULL); diff --git a/sflphone-client-gnome/src/actions.h b/sflphone-client-gnome/src/actions.h index 57823abd4d52d514622cfd2bbf9a128aaf8f3a1a..5cd2a7245d69369f0a8ab811e3e70415dbc22c10 100644 --- a/sflphone-client-gnome/src/actions.h +++ b/sflphone-client-gnome/src/actions.h @@ -301,4 +301,19 @@ void sflphone_call_state_changed (callable_obj_t * c, const gchar * description, * Resolve an interface address given its name */ void sflphone_get_interface_addr_from_name (char *iface_name, char **iface_addr, int size); + +void sflphone_add_main_participant (const conference_obj_t * c); + +void +sflphone_conference_off_hold (const conference_obj_t * c); + +void +sflphone_srtp_sdes_off (callable_obj_t * c); + +void sflphone_fill_conference_list (void); + +void sflphone_conference_on_hold (const conference_obj_t * c); + +void sflphone_conference_hang_up(); + #endif diff --git a/sflphone-client-gnome/src/callable_obj.c b/sflphone-client-gnome/src/callable_obj.c index 9a904e64adacdac262f689e916b1edf08283be8d..f3cf8e9efee6b219d00081b8d46bc4474cb4162d 100644 --- a/sflphone-client-gnome/src/callable_obj.c +++ b/sflphone-client-gnome/src/callable_obj.c @@ -32,10 +32,13 @@ #include <codeclist.h> #include <sflphone_const.h> #include <time.h> +#include "contacts/calltree.h" +#include <unistd.h> + #define UNIX_DAY 86400 #define UNIX_WEEK 86400 * 6 -#define UNIX_TWO_DAYS 86400 * 2 +#define UNIX_TWO_DAYS 86400 * 2 gint is_callID_callstruct (gconstpointer a, gconstpointer b) { @@ -125,12 +128,97 @@ void call_remove_all_errors (callable_obj_t * call) g_ptr_array_foreach (call->_error_dialogs, (GFunc) gtk_widget_destroy, NULL); } +void threaded_clock_incrementer (void *pc) +{ + + callable_obj_t *call = (callable_obj_t *) pc; + + + while (call->clockStarted) { + + int duration; + time_t start, current; + + gdk_threads_enter (); + + set_timestamp (& (call->_time_current)); + + start = call->_time_start; + current = call->_time_current; + + if (current == start) { + g_snprintf (call->_timestr, 20, "00:00"); + + } + + duration = (int) difftime (current, start); + + if (duration / 60 == 0) { + if (duration < 10) { + g_snprintf (call->_timestr, 20, "00:0%d", duration); + } else { + g_snprintf (call->_timestr, 20, "00:%d", duration); + } + } else { + if (duration%60 < 10) { + g_snprintf (call->_timestr, 20, "0%d:0%d", duration/60, duration%60); + } else { + g_snprintf (call->_timestr, 20, "%d:%d", duration/60, duration%60); + } + } + + // Update clock only if call is active (current, hold, recording transfer) + if ( (call->_state != CALL_STATE_INVALID) && + (call->_state != CALL_STATE_INCOMING) && + (call->_state != CALL_STATE_RINGING) && + (call->_state != CALL_STATE_DIALING) && + (call->_state != CALL_STATE_FAILURE) && + (call->_state != CALL_STATE_BUSY)) { + calltree_update_clock(); + } + + // gdk_flush(); + gdk_threads_leave (); + + + usleep (1000000); + + } + + DEBUG ("CallableObj: Stopping Thread"); + + g_thread_exit (NULL); + +} + +void stop_call_clock (callable_obj_t *c) +{ + + DEBUG ("CallableObj: Stop call clock"); + + if (!c) { + ERROR ("CallableObj: Callable object is NULL"); + return; + } + + if (c->_type == CALL && c->clockStarted) { + c->clockStarted = 0; + /// no need to join here, only need to call g_thread_exit at the end of the threaded function + // g_thread_join (c->tid); + } +} + void create_new_call (callable_type_t type, call_state_t state, gchar* callID , gchar* accountID, gchar* peer_name, gchar* peer_number, callable_obj_t ** new_call) { + GError *err1 = NULL ; callable_obj_t *obj; gchar *call_id; + DEBUG ("CallableObj: Create new call"); + + DEBUG ("Account: %s", accountID); + // Allocate memory obj = g_new0 (callable_obj_t, 1); @@ -148,7 +236,9 @@ void create_new_call (callable_type_t type, call_state_t state, gchar* callID , obj->_trsft_to = ""; set_timestamp (& (obj->_time_start)); + set_timestamp (& (obj->_time_current)); set_timestamp (& (obj->_time_stop)); + // g_snprintf(obj->_timestr, 20, "00:00"); if (g_strcasecmp (callID, "") == 0) call_id = generate_call_id (); @@ -159,6 +249,16 @@ void create_new_call (callable_type_t type, call_state_t state, gchar* callID , obj->_callID = g_strdup (call_id); obj->_confID = NULL; + obj->clockStarted = 1; + + if (obj->_type == CALL) { + // pthread_create(&(obj->tid), NULL, threaded_clock_incrementer, obj); + if ( (obj->tid = g_thread_create ( (GThreadFunc) threaded_clock_incrementer, (void *) obj, TRUE, &err1)) == NULL) { + DEBUG ("Thread creation failed!"); + g_error_free (err1) ; + } + } + *new_call = obj; } @@ -252,12 +352,20 @@ void create_history_entry_from_serialized_form (gchar *timestamp, gchar *details void free_callable_obj_t (callable_obj_t *c) { + DEBUG ("CallableObj: Free callable object"); + + stop_call_clock (c); + g_free (c->_callID); g_free (c->_accountID); g_free (c->_peer_name); g_free (c->_peer_number); g_free (c->_peer_info); g_free (c); + + DEBUG ("If you don't see it that is because there is a problem"); + + calltree_update_clock(); } void attach_thumbnail (callable_obj_t *call, GdkPixbuf *pixbuf) @@ -343,11 +451,14 @@ gchar* serialize_history_entry (callable_obj_t *entry) // and the timestamps timestamp = convert_timestamp_to_gchar (entry->_time_stop); + gchar* peer_name = (entry->_peer_name == NULL || g_strcasecmp (entry->_peer_name,"") == 0) ? "empty": entry->_peer_name; + gchar* account_id = (entry->_accountID == NULL || g_strcasecmp (entry->_accountID,"") == 0) ? "empty": entry->_accountID; + result = g_strconcat (history_state, separator, entry->_peer_number, separator, - g_strcasecmp (entry->_peer_name,"") ==0 ? "empty": entry->_peer_name, separator, + peer_name, separator, timestamp, separator, - g_strcasecmp (entry->_accountID,"") ==0 ? "empty": entry->_accountID, + account_id, NULL); return result; diff --git a/sflphone-client-gnome/src/callable_obj.h b/sflphone-client-gnome/src/callable_obj.h index 01114feeadc199a7130ee170b72c322e886c97e6..6f31d1942e0f44d8e969308e5f1c44802ed639dc 100644 --- a/sflphone-client-gnome/src/callable_obj.h +++ b/sflphone-client-gnome/src/callable_obj.h @@ -35,6 +35,7 @@ #include <glib/gprintf.h> #include <stdlib.h> #include <time.h> +#include <pthread.h> /** * @enum history_state @@ -106,7 +107,9 @@ typedef struct { gchar* _confID; // The conference ID (NULL if don't participate to a conference) gchar* _accountID; // The account the call is made with time_t _time_start; // The timestamp the call was initiating + time_t _time_current; // Clock increment to display call's elapsed time time_t _time_stop; // The timestamp the call was over + gchar _timestr[20]; // The timestamp as a string format for disply in statusbar history_state_t _history_state; // The history state if necessary srtp_state_t _srtp_state; // The state of security on the call gchar* _srtp_cipher; // Cipher used for the srtp session @@ -114,6 +117,7 @@ typedef struct { gboolean _zrtp_confirmed; // Override real state. Used for hold/unhold // since rtp session is killed each time and // libzrtpcpp does not remember state (yet?) + /** * The information about the person we are talking */ @@ -149,6 +153,12 @@ typedef struct { /* Associated IM widget */ GtkWidget *_im_widget; + // thread id to increment clock + // pthread_t tid; + GThread *tid; + + int clockStarted; + } callable_obj_t; void create_new_call (callable_type_t, call_state_t, gchar*, gchar*, gchar*, gchar*, callable_obj_t **); @@ -187,15 +197,15 @@ gchar* call_get_peer_name (const gchar*); */ gchar* call_get_peer_number (const gchar*); - - - void attach_thumbnail (callable_obj_t *, GdkPixbuf *); void free_callable_obj_t (callable_obj_t *c); +void +stop_call_clock (callable_obj_t *c); + /** * @return gchar* A random ID */ diff --git a/sflphone-client-gnome/src/codeclist.c b/sflphone-client-gnome/src/codeclist.c index edf36173976d55ff74b6b5cf208d4ad38eada7b1..284bc21d8168c45719217169377f0558eacc7dd2 100644 --- a/sflphone-client-gnome/src/codeclist.c +++ b/sflphone-client-gnome/src/codeclist.c @@ -32,6 +32,7 @@ #include <string.h> #include <stdlib.h> +#include <unistd.h> #include "dbus.h" @@ -113,18 +114,8 @@ void account_create_codec_list (account_t **acc) g_queue_free (_codecs); _codecs = g_queue_new (); - // _codecs = g_queue_copy (codecsCapabilities); (*acc)->codecs = _codecs; - // order = (gchar**) dbus_get_active_codec_list (acc->accountID); -} - -void account_set_codec_list (account_t **acc) -{ - - // Reset the codec list - // account_create_codec_list (a); - } void codec_create_new (gint payload, gboolean active, codec_t **c) @@ -326,7 +317,7 @@ void codec_list_update_to_daemon (account_t *acc) // Get all codecs in queue int c = 0; - unsigned int i = 0; + int i = 0; for (i = 0; i < length; i++) { codec_t* currentCodec = codec_list_get_nth (i, acc->codecs); diff --git a/sflphone-client-gnome/src/conference_obj.c b/sflphone-client-gnome/src/conference_obj.c index 90f0ffd679adc1158fe5bacbc7d8f2d5d3d0d20b..680a784b0f9e979f9ed07aa6ba532461b8bec5d6 100644 --- a/sflphone-client-gnome/src/conference_obj.c +++ b/sflphone-client-gnome/src/conference_obj.c @@ -43,7 +43,7 @@ gint is_confID_confstruct (gconstpointer a, gconstpointer b) } } -conference_obj_t* create_new_conference (conference_state_t state, const gchar* confID, conference_obj_t ** conf) +void create_new_conference (conference_state_t state, const gchar* confID, conference_obj_t ** conf) { DEBUG ("create_new_conference"); @@ -64,17 +64,14 @@ conference_obj_t* create_new_conference (conference_state_t state, const gchar* new_conf->participant_list = NULL; *conf = new_conf; - } -conference_obj_t* create_new_conference_from_details (const gchar *conf_id, GHashTable *details, conference_obj_t ** conf) +void create_new_conference_from_details (const gchar *conf_id, GHashTable *details, conference_obj_t ** conf) { DEBUG ("create_new_conference_from_details"); conference_obj_t *new_conf; - gchar* call_id; gchar** participants; - gchar** part; gchar* state_str; // GSList* participant_list; @@ -139,7 +136,7 @@ GSList* conference_next_participant (GSList* participant) } -GSList* conference_participant_list_update (gchar** participants, conference_obj_t* conf) +void conference_participant_list_update (gchar** participants, conference_obj_t* conf) { gchar* call_id; gchar** part; diff --git a/sflphone-client-gnome/src/conference_obj.h b/sflphone-client-gnome/src/conference_obj.h index 56f46e28dffa0b45bfc725356e8487c4e83b7b9d..edec21a7880ae38ad207da00753756949ff0c654 100644 --- a/sflphone-client-gnome/src/conference_obj.h +++ b/sflphone-client-gnome/src/conference_obj.h @@ -63,9 +63,9 @@ typedef struct { } conference_obj_t; -conference_obj_t* create_new_conference (conference_state_t, const gchar*, conference_obj_t **); +void create_new_conference (conference_state_t, const gchar*, conference_obj_t **); -conference_obj_t* create_new_conference_from_details (const gchar *, GHashTable *, conference_obj_t **); +void create_new_conference_from_details (const gchar *, GHashTable *, conference_obj_t **); void free_conference_obj_t (conference_obj_t *c); @@ -80,6 +80,6 @@ void conference_remove_participant (const gchar*, conference_obj_t *); GSList* conference_next_participant (GSList* participant); -GSList* conference_participant_list_update (gchar**, conference_obj_t*); +void conference_participant_list_update (gchar**, conference_obj_t*); #endif diff --git a/sflphone-client-gnome/src/config/accountconfigdialog.c b/sflphone-client-gnome/src/config/accountconfigdialog.c index a83857539c410b31cabffe8b96e768e9859082b8..cb718fb473500e5948af916154f1cd0b95824779 100644 --- a/sflphone-client-gnome/src/config/accountconfigdialog.c +++ b/sflphone-client-gnome/src/config/accountconfigdialog.c @@ -38,6 +38,7 @@ #include <accountconfigdialog.h> #include <zrtpadvanceddialog.h> #include <tlsadvanceddialog.h> +#include <audioconf.h> // From version 2.16, gtk provides the functionalities libsexy used to provide #if GTK_CHECK_VERSION(2,16,0) @@ -97,6 +98,8 @@ GtkWidget * publishedAddressLabel; GtkWidget * publishedPortLabel; GtkWidget * stunServerLabel; GtkWidget * stunServerEntry; +GtkWidget * enableTone; +GtkWidget * fileChooser; GtkWidget * displayNameEntry; @@ -119,10 +122,25 @@ enum { COLUMN_CREDENTIAL_COUNT }; +/* + * The same window is used with different configurations + * so we need to reset some data to prevent side-effects + */ +static void reset() +{ + entryAlias = NULL; + protocolComboBox = NULL; + entryHostname = NULL; + entryUsername = NULL; + entryPassword = NULL; + entryUseragent = NULL; + entryMailbox = NULL; +} + /* * Display / Hide the password */ -static void show_password_cb (GtkWidget *widget, gpointer data) +static void show_password_cb (GtkWidget *widget UNUSED, gpointer data) { gtk_entry_set_visibility (GTK_ENTRY (data), !gtk_entry_get_visibility (GTK_ENTRY (data))); } @@ -190,6 +208,11 @@ static GPtrArray* getNewCredential (GHashTable * properties) gchar *password; GHashTable * new_table; + if (valid == FALSE) { + DEBUG ("Gtk tree model iter is not valid"); + return NULL; + } + gtk_tree_model_get (GTK_TREE_MODEL (credentialStore), &iter, COLUMN_CREDENTIAL_REALM, &realm, COLUMN_CREDENTIAL_USERNAME, &username, @@ -207,7 +230,6 @@ static GPtrArray* getNewCredential (GHashTable * properties) g_hash_table_insert (properties, g_strdup (ACCOUNT_PASSWORD), password); - valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (credentialStore), &iter); while (valid) { @@ -261,7 +283,6 @@ static GtkWidget* create_basic_tab (account_t **a) gchar *curAccountType = "SIP"; gchar *curAlias = ""; gchar *curUsername = ""; - gchar *curRouteSet = ""; gchar *curHostname = ""; gchar *curPassword = ""; /* TODO: add curProxy, and add boxes for Proxy support */ @@ -272,11 +293,12 @@ static GtkWidget* create_basic_tab (account_t **a) int row = 0; + DEBUG ("Config: Create basic account tab"); + // Load from SIP/IAX/Unknown ? if (currentAccount) { curAccountID = currentAccount->accountID; curAccountType = g_hash_table_lookup (currentAccount->properties, ACCOUNT_TYPE); - DEBUG ("Config: Current accountType %s", curAccountType); curAccountEnabled = g_hash_table_lookup (currentAccount->properties, ACCOUNT_ENABLED); curAlias = g_hash_table_lookup (currentAccount->properties, ACCOUNT_ALIAS); curHostname = g_hash_table_lookup (currentAccount->properties, ACCOUNT_HOSTNAME); @@ -284,6 +306,7 @@ static GtkWidget* create_basic_tab (account_t **a) curUsername = g_hash_table_lookup (currentAccount->properties, ACCOUNT_USERNAME); // curRouteSet = g_hash_table_lookup(currentAccount->properties, ACCOUNT_ROUTE); curMailbox = g_hash_table_lookup (currentAccount->properties, ACCOUNT_MAILBOX); + curMailbox = curMailbox != NULL ? curMailbox : ""; curUseragent = g_hash_table_lookup (currentAccount->properties, ACCOUNT_USERAGENT); } @@ -368,29 +391,12 @@ static GtkWidget* create_basic_tab (account_t **a) g_object_set_data (G_OBJECT (entryUsername), "column", GINT_TO_POINTER (COLUMN_CREDENTIAL_USERNAME)); } - // Route set can be update only for SIP account - // TODO: uncomment this code and implement route - /* - if(strcmp(curAccountType, "SIP") == 0) { - row++; - label = gtk_label_new_with_mnemonic(_("_Route (optional)")); - gtk_table_attach(GTK_TABLE( table ), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); - entryRouteSet = gtk_entry_new(); - gtk_label_set_mnemonic_widget(GTK_LABEL(label), entryRouteSet); - gtk_entry_set_text(GTK_ENTRY(entryRouteSet), curRouteSet); - gtk_table_attach (GTK_TABLE(table), entryRouteSet, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - } - */ - row++; label = gtk_label_new_with_mnemonic (_ ("_Password")); gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); #if GTK_CHECK_VERSION(2,16,0) entryPassword = gtk_entry_new(); - GtkSettings *settings = gtk_settings_get_default (); - //g_object_set (G_OBJECT (settings), "gtk-entry-password-hint-timeout", 600, NULL); gtk_entry_set_icon_from_stock (GTK_ENTRY (entryPassword), GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_DIALOG_AUTHENTICATION); #else entryPassword = sexy_icon_entry_new(); @@ -441,33 +447,6 @@ static void fill_treeview_with_credential (GtkListStore * credentialStore, accou { GtkTreeIter iter; gtk_list_store_clear (credentialStore); - gtk_list_store_append (credentialStore, &iter); - - /* This is the default, undeletable credential */ - gchar * authentication_name = g_hash_table_lookup (account->properties, ACCOUNT_AUTHENTICATION_USERNAME); - gchar * realm = g_hash_table_lookup (account->properties, ACCOUNT_REALM); - - if (realm == NULL || (g_strcmp0 (realm, "") == 0)) { - realm = g_strdup ("*"); - } - - if ( (authentication_name == NULL) || (g_strcmp0 (authentication_name, "") == 0)) { - gtk_list_store_set (credentialStore, &iter, - COLUMN_CREDENTIAL_REALM, realm, - COLUMN_CREDENTIAL_USERNAME, gtk_entry_get_text (GTK_ENTRY (entryUsername)), - COLUMN_CREDENTIAL_PASSWORD, gtk_entry_get_text (GTK_ENTRY (entryPassword)), - COLUMN_CREDENTIAL_DATA, account, - -1); - } else { - gtk_list_store_set (credentialStore, &iter, - COLUMN_CREDENTIAL_REALM, g_hash_table_lookup (account->properties, ACCOUNT_REALM), - COLUMN_CREDENTIAL_USERNAME, g_hash_table_lookup (account->properties, ACCOUNT_AUTHENTICATION_USERNAME), - // COLUMN_CREDENTIAL_PASSWORD, gtk_entry_get_text(GTK_ENTRY(entryPassword)), - COLUMN_CREDENTIAL_PASSWORD, PW_HIDDEN, - COLUMN_CREDENTIAL_DATA, account, - -1); - g_signal_handlers_disconnect_by_func (G_OBJECT (entryUsername), G_CALLBACK (update_credential_cb), NULL); - } if (account->credential_information == NULL) { DEBUG ("No credential defined"); @@ -483,12 +462,11 @@ static void fill_treeview_with_credential (GtkListStore * credentialStore, accou COLUMN_CREDENTIAL_REALM, g_hash_table_lookup (element, ACCOUNT_REALM), COLUMN_CREDENTIAL_USERNAME, g_hash_table_lookup (element, ACCOUNT_USERNAME), COLUMN_CREDENTIAL_PASSWORD, g_hash_table_lookup (element, ACCOUNT_PASSWORD), - COLUMN_CREDENTIAL_DATA, element, // Pointer - -1); + COLUMN_CREDENTIAL_DATA, element, -1); } } -static select_credential_cb (GtkTreeSelection *selection, GtkTreeModel *model) +static void select_credential_cb (GtkTreeSelection *selection, GtkTreeModel *model) { GtkTreeIter iter; GtkTreePath *path; @@ -504,7 +482,7 @@ static select_credential_cb (GtkTreeSelection *selection, GtkTreeModel *model) } } -static void add_credential_cb (GtkWidget *button, gpointer data) +static void add_credential_cb (GtkWidget *button UNUSED, gpointer data) { GtkTreeIter iter; GtkTreeModel *model = (GtkTreeModel *) data; @@ -517,7 +495,7 @@ static void add_credential_cb (GtkWidget *button, gpointer data) -1); } -static void delete_credential_cb (GtkWidget *button, gpointer data) +static void delete_credential_cb (GtkWidget *button UNUSED, gpointer data) { GtkTreeIter iter; GtkTreeView *treeview = (GtkTreeView *) data; @@ -560,7 +538,7 @@ static void cell_edited_cb (GtkCellRendererText *renderer, gchar *path_desc, gch } -static void editing_started_cb (GtkCellRenderer *cell, GtkCellEditable * editable, const gchar * path, gpointer data) +static void editing_started_cb (GtkCellRenderer *cell UNUSED, GtkCellEditable * editable, const gchar * path, gpointer data UNUSED) { DEBUG ("Editing started"); @@ -591,7 +569,7 @@ static void show_advanced_tls_options_cb (GtkWidget *widget UNUSED, gpointer dat show_advanced_tls_options ( (GHashTable *) data); } -static void key_exchange_changed_cb (GtkWidget *widget, gpointer data) +static void key_exchange_changed_cb (GtkWidget *widget UNUSED, gpointer data UNUSED) { DEBUG ("Key exchange changed %s", gtk_combo_box_get_active_text (GTK_COMBO_BOX (keyExchangeCombo))); @@ -654,7 +632,7 @@ static void use_sip_tls_cb (GtkWidget *widget, gpointer data) } } -static local_interface_changed_cb (GtkWidget * widget, gpointer data UNUSED) +static void local_interface_changed_cb (GtkWidget * widget UNUSED, gpointer data UNUSED) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sameAsLocalRadioButton))) { @@ -664,22 +642,18 @@ static local_interface_changed_cb (GtkWidget * widget, gpointer data UNUSED) local_iface_addr = g_malloc (36); local_iface_name = (gchar *) gtk_combo_box_get_active_text (GTK_COMBO_BOX (localAddressCombo)); - // sflphone_get_interface_addr_from_name((char *)local_interface); sflphone_get_interface_addr_from_name (local_iface_name, &local_iface_addr, 36); gtk_entry_set_text (GTK_ENTRY (localAddressEntry), local_iface_addr); gtk_entry_set_text (GTK_ENTRY (publishedAddressEntry), local_iface_addr); - // gchar * local_port = (gchar *) gtk_entry_get_text(GTK_ENTRY(localPortSpinBox)); - // gtk_spin_button_set_value(GTK_SPIN_BUTTON(publishedPortSpinBox), g_ascii_strtod(local_port, NULL)); g_free (local_iface_addr); } } -static set_published_addr_manually_cb (GtkWidget * widget, gpointer data UNUSED) +static void set_published_addr_manually_cb (GtkWidget * widget, gpointer data UNUSED) { - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { DEBUG ("Config: Showing manual publishing options"); gtk_widget_show (publishedPortLabel); @@ -695,11 +669,8 @@ static set_published_addr_manually_cb (GtkWidget * widget, gpointer data UNUSED) } } -static use_stun_cb (GtkWidget *widget, gpointer data UNUSED) +static void use_stun_cb (GtkWidget *widget, gpointer data UNUSED) { - gchar *local_interface; - gchar *local_address; - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { DEBUG ("Config: Showing stun options, hiding Local/Published info"); @@ -732,7 +703,7 @@ static use_stun_cb (GtkWidget *widget, gpointer data UNUSED) } -static same_as_local_cb (GtkWidget * widget, gpointer data UNUSED) +static void same_as_local_cb (GtkWidget * widget, gpointer data UNUSED) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { @@ -816,7 +787,9 @@ GtkWidget* create_credential_widget (account_t **a) gtk_container_add (GTK_CONTAINER (scrolledWindowCredential), treeViewCredential); + DEBUG ("Credential pas ok"); fill_treeview_with_credential (credentialStore, *a); + DEBUG ("Credential ok"); /* Credential Buttons */ hbox = gtk_hbox_new (FALSE, 10); @@ -928,8 +901,6 @@ GtkWidget * create_security_tab (account_t **a) { GtkWidget * frame; GtkWidget * ret; - GtkWidget * hbox; - ret = gtk_vbox_new (FALSE, 10); gtk_container_set_border_width (GTK_CONTAINER (ret), 10); @@ -985,7 +956,8 @@ GtkWidget* create_network (account_t **a) { GtkWidget *table, *frame, *label; - gchar *local_interface, *local_port; + gchar *local_interface = NULL; + gchar *local_port = NULL; if (*a) { local_interface = g_hash_table_lookup ( (*a)->properties, LOCAL_INTERFACE); @@ -1087,8 +1059,13 @@ GtkWidget* create_network (account_t **a) GtkWidget* create_published_address (account_t **a) { - GtkWidget *table, *frame, *label; - gchar *use_tls, *published_address, *published_port, *local_address, *stun_enable, *stun_server, *published_sameas_local; + GtkWidget *table, *frame; + gchar *use_tls =NULL; + gchar *published_address = NULL; + gchar *published_port = NULL; + gchar *stun_enable = NULL; + gchar *stun_server = NULL; + gchar *published_sameas_local = NULL; // Get the user configuration if (*a) { @@ -1178,7 +1155,7 @@ GtkWidget* create_advanced_tab (account_t **a) { // Build the advanced tab, to appear on the account configuration panel - DEBUG ("Config: Build advanced tab") + DEBUG ("Config: Build advanced tab"); GtkWidget *ret, *frame; @@ -1203,6 +1180,18 @@ GtkWidget* create_advanced_tab (account_t **a) return ret; } +void ringtone_enabled (GtkWidget *widget UNUSED, gpointer fileChooser, const gchar *accountID UNUSED) +{ + gboolean isEnabled = gtk_widget_get_sensitive (GTK_WIDGET (fileChooser)); + + if (isEnabled) { + gtk_widget_set_sensitive (GTK_WIDGET (fileChooser), FALSE); + } else { + gtk_widget_set_sensitive (GTK_WIDGET (fileChooser), TRUE); + } +} + + GtkWidget* create_codecs_configuration (account_t **a) { @@ -1252,6 +1241,36 @@ GtkWidget* create_codecs_configuration (account_t **a) gtk_table_attach (GTK_TABLE (table), sipinfo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); } + // Box for the ringtones + gnome_main_section_new_with_table (_ ("Ringtones"), &frame, &table, 1, 2); + gtk_box_pack_start (GTK_BOX (ret), frame, FALSE, FALSE, 0); + + fileChooser = gtk_file_chooser_button_new (_ ("Choose a ringtone"), GTK_FILE_CHOOSER_ACTION_OPEN); + + p = g_hash_table_lookup (currentAccount->properties, g_strdup (CONFIG_RINGTONE_ENABLED)); + gboolean ringtoneEnabled = (g_strcmp0 (p, "true") == 0) ? TRUE : FALSE; + + enableTone = gtk_check_button_new_with_mnemonic (_ ("_Enable ringtones")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enableTone), ringtoneEnabled); + g_signal_connect (G_OBJECT (enableTone) , "clicked" , G_CALLBACK (ringtone_enabled), fileChooser); + gtk_table_attach (GTK_TABLE (table), enableTone, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + // file chooser button + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (fileChooser) , g_get_home_dir()); + p = g_hash_table_lookup (currentAccount->properties, g_strdup (CONFIG_RINGTONE_PATH)); + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (fileChooser) , p); + gtk_widget_set_sensitive (GTK_WIDGET (fileChooser), ringtoneEnabled); + + GtkFileFilter *filter = gtk_file_filter_new(); + gtk_file_filter_set_name (filter , _ ("Audio Files")); + gtk_file_filter_add_pattern (filter , "*.wav"); + gtk_file_filter_add_pattern (filter , "*.ul"); + gtk_file_filter_add_pattern (filter , "*.au"); + gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fileChooser) , filter); + gtk_table_attach (GTK_TABLE (table), fileChooser, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + + gtk_widget_show_all (ret); return ret; @@ -1266,6 +1285,10 @@ void show_account_window (account_t * a) gint response; account_t *currentAccount; + + // Firstly we reset + reset(); + // In case the published address is same than local, // we must resolve published address from interface name gchar * local_interface; @@ -1367,8 +1390,6 @@ void show_account_window (account_t * a) return; } - gchar *key = g_strdup (ACCOUNT_USERNAME); - // If accept button is if (g_strcasecmp (currentAccount->accountID, IP2IP) != 0) { @@ -1450,32 +1471,43 @@ void show_account_window (account_t * a) published_address); } - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (overrtp))) { - g_hash_table_replace (currentAccount->properties, g_strdup (ACCOUNT_DTMF_TYPE), g_strdup (OVERRTP)); - } else { - g_hash_table_replace (currentAccount->properties, g_strdup (ACCOUNT_DTMF_TYPE), g_strdup (SIPINFO)); - } + } - gchar* keyExchange = (gchar *) gtk_combo_box_get_active_text (GTK_COMBO_BOX (keyExchangeCombo)); + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (overrtp))) { + g_hash_table_replace (currentAccount->properties, g_strdup (ACCOUNT_DTMF_TYPE), g_strdup (OVERRTP)); + } else { + g_hash_table_replace (currentAccount->properties, g_strdup (ACCOUNT_DTMF_TYPE), g_strdup (SIPINFO)); + } - if (g_strcasecmp (keyExchange, "ZRTP") == 0) { - g_hash_table_replace (currentAccount->properties, g_strdup (ACCOUNT_SRTP_ENABLED), g_strdup ("true")); - g_hash_table_replace (currentAccount->properties, g_strdup (ACCOUNT_KEY_EXCHANGE), g_strdup (ZRTP)); - } + gchar* keyExchange = (gchar *) gtk_combo_box_get_active_text (GTK_COMBO_BOX (keyExchangeCombo)); - else if (g_strcasecmp (keyExchange, "SDES") == 0) { - g_hash_table_replace (currentAccount->properties, g_strdup (ACCOUNT_SRTP_ENABLED), g_strdup ("true")); - g_hash_table_replace (currentAccount->properties, g_strdup (ACCOUNT_KEY_EXCHANGE), g_strdup (SDES)); - } + if (g_strcasecmp (keyExchange, "ZRTP") == 0) { + g_hash_table_replace (currentAccount->properties, g_strdup (ACCOUNT_SRTP_ENABLED), g_strdup ("true")); + g_hash_table_replace (currentAccount->properties, g_strdup (ACCOUNT_KEY_EXCHANGE), g_strdup (ZRTP)); + } - else { - g_hash_table_replace (currentAccount->properties, g_strdup (ACCOUNT_SRTP_ENABLED), g_strdup ("false")); - } + else if (g_strcasecmp (keyExchange, "SDES") == 0) { + g_hash_table_replace (currentAccount->properties, g_strdup (ACCOUNT_SRTP_ENABLED), g_strdup ("true")); + g_hash_table_replace (currentAccount->properties, g_strdup (ACCOUNT_KEY_EXCHANGE), g_strdup (SDES)); + } - g_hash_table_replace (currentAccount->properties, g_strdup (TLS_ENABLE), - g_strdup (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (useSipTlsCheckBox)) ? "true":"false")); + else { + g_hash_table_replace (currentAccount->properties, g_strdup (ACCOUNT_SRTP_ENABLED), g_strdup ("false")); } + g_hash_table_replace (currentAccount->properties, g_strdup (TLS_ENABLE), + g_strdup (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (useSipTlsCheckBox)) ? "true":"false")); + + gboolean toneEnabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (enableTone)); + g_hash_table_replace (currentAccount->properties, + g_strdup (CONFIG_RINGTONE_ENABLED), + g_strdup (toneEnabled ? "true" : "false")); + + + g_hash_table_replace (currentAccount->properties, + g_strdup (CONFIG_RINGTONE_PATH), + g_strdup ( (gchar *) gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fileChooser)))); + g_hash_table_replace (currentAccount->properties, g_strdup (LOCAL_INTERFACE), g_strdup ( (gchar *) gtk_combo_box_get_active_text (GTK_COMBO_BOX (localAddressCombo)))); @@ -1500,17 +1532,17 @@ void show_account_window (account_t * a) */ dbus_delete_all_credential (currentAccount); + DEBUG ("Config: Get new credentials"); GPtrArray * credential = getNewCredential (currentAccount->properties); currentAccount->credential_information = credential; if (currentAccount->credential_information != NULL) { - int i; + guint i; for (i = 0; i < currentAccount->credential_information->len; i++) { + DEBUG ("Create new credential"); dbus_set_credential (currentAccount, i); } - - dbus_set_number_of_credential (currentAccount, currentAccount->credential_information->len); } } } diff --git a/sflphone-client-gnome/src/config/accountlistconfigdialog.c b/sflphone-client-gnome/src/config/accountlistconfigdialog.c index bf9887cfabd8e19e2d1ec4fb662ed27234fe472e..eddf58f7dc177ce82b1f8d51f6d8200f5e59bfd0 100644 --- a/sflphone-client-gnome/src/config/accountlistconfigdialog.c +++ b/sflphone-client-gnome/src/config/accountlistconfigdialog.c @@ -36,6 +36,7 @@ #include <actions.h> #include <utils.h> #include <string.h> +#include <libgnome/gnome-help.h> #define CONTEXT_ID_REGISTRATION 0 @@ -61,6 +62,38 @@ enum { COLUMN_ACCOUNT_COUNT }; +/** + * Delete an account + */ +static void delete_account_cb (void) +{ + + if (selectedAccount != NULL) { + dbus_remove_account (selectedAccount->accountID); + } +} + + +/** + * Edit an account + */ +static void edit_account_cb (void) +{ + + if (selectedAccount != NULL) { + show_account_window (selectedAccount); + } +} + +/** + * Add an account + */ +static void add_account_cb (void) +{ + + show_account_window (NULL); +} + /** * Fills the treelist with accounts */ @@ -303,12 +336,11 @@ account_move_down_cb (GtkButton *button UNUSED, gpointer data) } static void -help_contents_cb (GtkWidget * widget, +help_contents_cb (GtkWidget * widget UNUSED, gpointer data UNUSED) { GError *error = NULL; - //gboolean success = gtk_show_uri (NULL, "ghelp: sflphone.xml", GDK_CURRENT_TIME, &error); gnome_help_display ("sflphone.xml", "accounts", &error); if (error != NULL) { @@ -319,14 +351,14 @@ help_contents_cb (GtkWidget * widget, } static void -close_dialog_cb (GtkWidget * widget, +close_dialog_cb (GtkWidget * widget UNUSED, gpointer data UNUSED) { gtk_dialog_response (GTK_DIALOG (accountListDialog), GTK_RESPONSE_ACCEPT); } -void highlight_ip_profile (GtkTreeViewColumn *col, GtkCellRenderer *rend, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) +void highlight_ip_profile (GtkTreeViewColumn *col UNUSED, GtkCellRenderer *rend, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data UNUSED) { GValue val; @@ -354,12 +386,11 @@ void highlight_ip_profile (GtkTreeViewColumn *col, GtkCellRenderer *rend, GtkTre } } -void highlight_registration (GtkTreeViewColumn *col, GtkCellRenderer *rend, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data) +void highlight_registration (GtkTreeViewColumn *col UNUSED, GtkCellRenderer *rend, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data UNUSED) { GValue val; account_t *current; - GdkColor green = {0, 255, 0, 0}; memset (&val, 0, sizeof (val)); gtk_tree_model_get_value (tree_model, iter, COLUMN_ACCOUNT_DATA, &val); @@ -381,7 +412,7 @@ void highlight_registration (GtkTreeViewColumn *col, GtkCellRenderer *rend, GtkT /** * Account settings tab */ -GtkWidget* create_account_list (GtkDialog * dialog) +GtkWidget* create_account_list (GtkDialog * dialog UNUSED) { GtkWidget *table, *scrolledWindow, *buttonBox; @@ -575,35 +606,3 @@ show_account_list_config_dialog (void) update_actions (); } - -/** - * Delete an account - */ -static void delete_account_cb (void) -{ - - if (selectedAccount != NULL) { - dbus_remove_account (selectedAccount->accountID); - } -} - - -/** - * Edit an account - */ -static void edit_account_cb (void) -{ - - if (selectedAccount != NULL) { - show_account_window (selectedAccount); - } -} - -/** - * Add an account - */ -static void add_account_cb (void) -{ - - show_account_window (NULL); -} diff --git a/sflphone-client-gnome/src/config/accountlistconfigdialog.h b/sflphone-client-gnome/src/config/accountlistconfigdialog.h index d2b4c5e0e163efd3e36148962f7351bac813f86c..090d124962724c1104353bd724a1436f5daa0519 100644 --- a/sflphone-client-gnome/src/config/accountlistconfigdialog.h +++ b/sflphone-client-gnome/src/config/accountlistconfigdialog.h @@ -37,10 +37,4 @@ void show_account_list_config_dialog (void); void account_list_config_dialog_fill (void); -static void delete_account_cb (void); - -static void add_account_cb (void); - -static void edit_account_cb (void); - #endif diff --git a/sflphone-client-gnome/src/config/addressbook-config.c b/sflphone-client-gnome/src/config/addressbook-config.c index ae08d55b2fea17e50bab04607871322b6c74a4f6..7f0d2256b181db7e19a7e7dfd3cc9508078de522 100644 --- a/sflphone-client-gnome/src/config/addressbook-config.c +++ b/sflphone-client-gnome/src/config/addressbook-config.c @@ -29,6 +29,7 @@ */ #include "addressbook-config.h" +#include "searchbar.h" #include <contacts/addressbook/eds.h> #include <string.h> #include <stdlib.h> @@ -56,27 +57,29 @@ addressbook_config_load_parameters (AddressBook_Config **settings) _params = (GHashTable*) dbus_get_addressbook_settings(); if (_params == NULL) { + + DEBUG ("Addressbook: No parameters received, use default"); + _settings->enable = 1; _settings->max_results = 30; _settings->display_contact_photo = 0; _settings->search_phone_business = 1; _settings->search_phone_home = 1; _settings->search_phone_mobile = 1; + } else { - _settings->enable = (gint64) (g_hash_table_lookup (_params, - ADDRESSBOOK_ENABLE)); - _settings->max_results = (gint64) (g_hash_table_lookup (_params, - ADDRESSBOOK_MAX_RESULTS)); - _settings->display_contact_photo = (gint64) (g_hash_table_lookup (_params, - ADDRESSBOOK_DISPLAY_CONTACT_PHOTO)); - _settings->search_phone_business = (gint64) (g_hash_table_lookup (_params, - ADDRESSBOOK_DISPLAY_PHONE_BUSINESS)); - _settings->search_phone_home = (gint64) (g_hash_table_lookup (_params, - ADDRESSBOOK_DISPLAY_PHONE_HOME)); - _settings->search_phone_mobile = (gint64) (g_hash_table_lookup (_params, - ADDRESSBOOK_DISPLAY_PHONE_MOBILE)); + _settings->enable = (size_t) (g_hash_table_lookup (_params, ADDRESSBOOK_ENABLE)); + _settings->max_results = (size_t) (g_hash_table_lookup (_params, ADDRESSBOOK_MAX_RESULTS)); + _settings->display_contact_photo = (size_t) (g_hash_table_lookup (_params, ADDRESSBOOK_DISPLAY_CONTACT_PHOTO)); + _settings->search_phone_business = (size_t) (g_hash_table_lookup (_params, ADDRESSBOOK_DISPLAY_PHONE_BUSINESS)); + _settings->search_phone_home = (size_t) (g_hash_table_lookup (_params, ADDRESSBOOK_DISPLAY_PHONE_HOME)); + _settings->search_phone_mobile = (size_t) (g_hash_table_lookup (_params, ADDRESSBOOK_DISPLAY_PHONE_MOBILE)); } + DEBUG ("Addressbook: Settings: enabled %d, max_result %d, photo %d, business %d, home %d, mobile %d", + _settings->enable, _settings->max_results, _settings->display_contact_photo, + _settings->search_phone_business, _settings->search_phone_home, _settings->search_phone_mobile); + *settings = _settings; } @@ -88,20 +91,22 @@ addressbook_config_save_parameters (void) params = g_hash_table_new (NULL, g_str_equal); g_hash_table_replace (params, (gpointer) ADDRESSBOOK_ENABLE, - (gpointer) addressbook_config->enable); + (gpointer) (size_t) addressbook_config->enable); g_hash_table_replace (params, (gpointer) ADDRESSBOOK_MAX_RESULTS, - (gpointer) addressbook_config->max_results); + (gpointer) (size_t) addressbook_config->max_results); g_hash_table_replace (params, (gpointer) ADDRESSBOOK_DISPLAY_CONTACT_PHOTO, - (gpointer) addressbook_config->display_contact_photo); + (gpointer) (size_t) addressbook_config->display_contact_photo); g_hash_table_replace (params, (gpointer) ADDRESSBOOK_DISPLAY_PHONE_BUSINESS, - (gpointer) addressbook_config->search_phone_business); + (gpointer) (size_t) addressbook_config->search_phone_business); g_hash_table_replace (params, (gpointer) ADDRESSBOOK_DISPLAY_PHONE_HOME, - (gpointer) addressbook_config->search_phone_home); + (gpointer) (size_t) addressbook_config->search_phone_home); g_hash_table_replace (params, (gpointer) ADDRESSBOOK_DISPLAY_PHONE_MOBILE, - (gpointer) addressbook_config->search_phone_mobile); + (gpointer) (size_t) addressbook_config->search_phone_mobile); dbus_set_addressbook_settings (params); + update_searchbar_addressbook_list(); + // Decrement the reference count g_hash_table_unref (params); } @@ -292,7 +297,7 @@ GtkWidget* create_addressbook_settings() { - GtkWidget *ret, *result_frame, *table, *value, *label, *item; + GtkWidget *ret, *result_frame, *table, *value, *item; GtkListStore *store; GtkCellRenderer *renderer; diff --git a/sflphone-client-gnome/src/config/addressbook-config.h b/sflphone-client-gnome/src/config/addressbook-config.h index 2a534e5ebac8625196246cd0930948eed1aecb15..cd03bba833a9da0249424b49d91800b00bfd6eac 100644 --- a/sflphone-client-gnome/src/config/addressbook-config.h +++ b/sflphone-client-gnome/src/config/addressbook-config.h @@ -49,12 +49,12 @@ G_BEGIN_DECLS typedef struct _AddressBook_Config { // gint64: a signed integer guaranteed to be 64 bits on all platforms // To print or scan values of this type, use G_GINT64_MODIFIER and/or G_GINT64_FORMAT - gint64 enable; - gint64 max_results; - gint64 display_contact_photo; - gint64 search_phone_home; - gint64 search_phone_business; - gint64 search_phone_mobile; + gint enable; + gint max_results; + gint display_contact_photo; + gint search_phone_home; + gint search_phone_business; + gint search_phone_mobile; } AddressBook_Config; /** diff --git a/sflphone-client-gnome/src/config/assistant.c b/sflphone-client-gnome/src/config/assistant.c index 8b1f7d3a288e589e2a70f0fb1818a2d921436a5a..71d3d654407f346ab3b413d15416179b99faefa0 100644 --- a/sflphone-client-gnome/src/config/assistant.c +++ b/sflphone-client-gnome/src/config/assistant.c @@ -71,7 +71,7 @@ void set_account_type (GtkWidget* widget , gpointer data UNUSED) } } -static void show_password_cb (GtkWidget *widget, gpointer data) +static void show_password_cb (GtkWidget *widget UNUSED, gpointer data) { gtk_entry_set_visibility (GTK_ENTRY (data), !gtk_entry_get_visibility (GTK_ENTRY (data))); } @@ -331,7 +331,6 @@ GtkWidget* build_sip_account_configuration (void) { GtkWidget* table; GtkWidget* label; - GtkWidget *image; GtkWidget * clearTextCheckbox; wiz->sip_account = create_vbox (GTK_ASSISTANT_PAGE_CONTENT , _ ("SIP account settings") , _ ("Please fill the following information")); @@ -446,7 +445,6 @@ GtkWidget* build_iax_account_configuration (void) { GtkWidget* label; GtkWidget* table; - GtkWidget *image; GtkWidget * clearTextCheckbox; wiz->iax_account = create_vbox (GTK_ASSISTANT_PAGE_CONFIRM , _ ("IAX2 account settings") , _ ("Please fill the following information")); diff --git a/sflphone-client-gnome/src/config/audioconf.c b/sflphone-client-gnome/src/config/audioconf.c index 4dd871fdffc2e3b0ca944121274312b66b38d8e2..6f767ea32ff912fb6e0f4bc0777307f768c4fdbc 100644 --- a/sflphone-client-gnome/src/config/audioconf.c +++ b/sflphone-client-gnome/src/config/audioconf.c @@ -31,6 +31,8 @@ #include <audioconf.h> #include <utils.h> #include <string.h> +#include <eel-gconf-extensions.h> +#include "dbus/dbus.h" GtkListStore *pluginlist; GtkListStore *outputlist; @@ -352,7 +354,7 @@ select_output_audio_plugin (GtkComboBox* widget, gpointer data UNUSED) model = gtk_combo_box_get_model (widget); gtk_combo_box_get_active_iter (widget, &iter); gtk_tree_model_get (model, &iter, 0, &pluginName, -1); - dbus_set_output_audio_plugin (pluginName); + dbus_set_audio_plugin (pluginName); //update_combo_box( pluginName); } } @@ -437,9 +439,10 @@ select_audio_input_device (GtkComboBox* comboBox, gpointer data UNUSED) } } + /** - * Set the audio ringtone device on the server with its index - */ ++ * Set the audio ringtone device on the server with its index ++ */ static void select_audio_ringtone_device (GtkComboBox *comboBox, gpointer data UNUSED) { @@ -460,6 +463,7 @@ select_audio_ringtone_device (GtkComboBox *comboBox, gpointer data UNUSED) } } + /** * Toggle move buttons on if a codec is selected, off elsewise */ @@ -553,7 +557,6 @@ static void codec_move (gboolean moveUp, gpointer data) GtkTreeIter iter; GtkTreeIter *iter2; - GtkTreeView *treeView; GtkTreeModel *model; GtkTreeSelection *selection; GtkTreePath *treePath; @@ -629,32 +632,6 @@ static void codec_move_down (GtkButton *button UNUSED, gpointer data) codec_move (FALSE, data); } -int -is_ringtone_enabled (void) -{ - return dbus_is_ringtone_enabled(); -} - -void -ringtone_enabled (void) -{ - dbus_ringtone_enabled(); -} - -void -ringtone_changed (GtkFileChooser *chooser , GtkLabel *label UNUSED) -{ - gchar* tone = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser)); - dbus_set_ringtone_choice (tone); -} - -gchar* -get_ringtone_choice (void) -{ - return dbus_get_ringtone_choice(); -} - - GtkWidget* codecs_box (account_t **a) { GtkWidget *ret; @@ -892,14 +869,6 @@ GtkWidget* alsa_box() gtk_label_set_mnemonic_widget (GTK_LABEL (item), input); g_signal_connect (G_OBJECT (input), "changed", G_CALLBACK (select_audio_input_device), input); - // Set rendering - renderer = gtk_cell_renderer_text_new(); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (input), renderer, TRUE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (input), renderer, "text", 0, NULL); - gtk_table_attach (GTK_TABLE (table), input, 2, 3, 3, 4, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0); - gtk_widget_show (input); - - DEBUG ("Audio: Configuration rintgtone"); item = gtk_label_new (_ ("Ringtone")); gtk_misc_set_alignment (GTK_MISC (item), 0, 0.5); @@ -920,51 +889,17 @@ GtkWidget* alsa_box() gtk_table_attach (GTK_TABLE (table), ringtone, 2, 3, 4, 5, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0); gtk_widget_show (ringtone); - gtk_widget_show_all (ret); - - DEBUG ("done"); - return ret; -} - -GtkWidget* noise_box() -{ - GtkWidget *ret; - GtkWidget *enableEchoCancel; - GtkWidget *enableNoiseReduction; - gboolean echocancelActive, noisesuppressActive; - gchar *state; - - ret = gtk_hbox_new (TRUE , 1); - - enableEchoCancel = gtk_check_button_new_with_mnemonic (_ ("_Echo Suppression")); - state = dbus_get_echo_cancel_state(); - echocancelActive = FALSE; - - if (strcmp (state, "enabled") == 0) - echocancelActive = TRUE; - else - echocancelActive = FALSE; - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enableEchoCancel), echocancelActive); - g_signal_connect (G_OBJECT (enableEchoCancel), "clicked", active_echo_cancel, NULL); - - gtk_box_pack_start (GTK_BOX (ret), enableEchoCancel, TRUE , TRUE , 1); - - - enableNoiseReduction = gtk_check_button_new_with_mnemonic (_ ("_Noise Reduction")); - state = dbus_get_noise_suppress_state(); - noisesuppressActive = FALSE; - - if (strcmp (state, "enabled") == 0) - noisesuppressActive = TRUE; - else - noisesuppressActive = FALSE; - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enableNoiseReduction), noisesuppressActive); - gtk_box_pack_start (GTK_BOX (ret) , enableNoiseReduction , TRUE , TRUE , 1); + // Set rendering + renderer = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (input), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (input), renderer, "text", 0, NULL); + gtk_table_attach (GTK_TABLE (table), input, 2, 3, 3, 4, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0); + gtk_widget_show (input); - g_signal_connect (G_OBJECT (enableNoiseReduction), "clicked", active_noise_suppress, NULL); + gtk_widget_show_all (ret); + DEBUG ("done"); return ret; } @@ -983,8 +918,11 @@ GtkWidget* create_audio_configuration() // Main widget GtkWidget *ret; // Sub boxes - GtkWidget *box; GtkWidget *frame; + GtkWidget *enableEchoCancel; + GtkWidget *enableNoiseReduction; + gboolean echocancelActive, noisesuppressActive; + gchar *state; ret = gtk_vbox_new (FALSE, 10); gtk_container_set_border_width (GTK_CONTAINER (ret), 10); @@ -1018,7 +956,6 @@ GtkWidget* create_audio_configuration() if (SHOW_ALSA_CONF) { // Box for the ALSA configuration - printf ("ALSA Created \n"); alsabox = alsa_box(); gtk_container_add (GTK_CONTAINER (alsa_conf) , alsabox); gtk_widget_hide (alsa_conf); @@ -1046,40 +983,36 @@ GtkWidget* create_audio_configuration() g_signal_connect (G_OBJECT (folderChooser) , "selection_changed" , G_CALLBACK (record_path_changed) , NULL); gtk_table_attach (GTK_TABLE (table), folderChooser, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 5); - // Box for the ringtones - gnome_main_section_new_with_table (_ ("Ringtones"), &frame, &table, 1, 2); - gtk_box_pack_start (GTK_BOX (ret), frame, FALSE, FALSE, 0); - GtkWidget *enableTone; - GtkWidget *fileChooser; + // Box for the voice enhancement configuration + gnome_main_section_new_with_table (_ ("Voice enhancement settings"), &frame, &table, 2, 1); + gtk_box_pack_start (GTK_BOX (ret), frame, FALSE, FALSE, 0); - enableTone = gtk_check_button_new_with_mnemonic (_ ("_Enable ringtones")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enableTone), dbus_is_ringtone_enabled()); - g_signal_connect (G_OBJECT (enableTone) , "clicked" , G_CALLBACK (ringtone_enabled) , NULL); - gtk_table_attach (GTK_TABLE (table), enableTone, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + enableEchoCancel = gtk_check_button_new_with_mnemonic (_ ("_Echo Suppression")); + state = dbus_get_echo_cancel_state(); + echocancelActive = FALSE; - // file chooser button - fileChooser = gtk_file_chooser_button_new (_ ("Choose a ringtone"), GTK_FILE_CHOOSER_ACTION_OPEN); - gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (fileChooser) , g_get_home_dir()); - gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (fileChooser) , get_ringtone_choice()); - g_signal_connect (G_OBJECT (fileChooser) , "selection_changed" , G_CALLBACK (ringtone_changed) , NULL); + if (strcmp (state, "enabled") == 0) + echocancelActive = TRUE; + else + echocancelActive = FALSE; - GtkFileFilter *filter = gtk_file_filter_new(); - gtk_file_filter_set_name (filter , _ ("Audio Files")); - gtk_file_filter_add_pattern (filter , "*.wav"); - gtk_file_filter_add_pattern (filter , "*.ul"); - gtk_file_filter_add_pattern (filter , "*.au"); - gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fileChooser) , filter); - gtk_table_attach (GTK_TABLE (table), fileChooser, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enableEchoCancel), echocancelActive); + g_signal_connect (G_OBJECT (enableEchoCancel), "clicked", active_echo_cancel, NULL); + gtk_table_attach (GTK_TABLE (table), enableEchoCancel, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gnome_main_section_new (_ ("Voice enhancement settings"), &noise_conf); - gtk_box_pack_start (GTK_BOX (ret), noise_conf, FALSE, FALSE, 0); - gtk_widget_show (noise_conf); + enableNoiseReduction = gtk_check_button_new_with_mnemonic (_ ("_Noise Reduction")); + state = dbus_get_noise_suppress_state(); + noisesuppressActive = FALSE; - // Box for the voice enhancement configuration - noisebox = noise_box(); - gtk_container_add (GTK_CONTAINER (noise_conf) , noisebox); + if (strcmp (state, "enabled") == 0) + noisesuppressActive = TRUE; + else + noisesuppressActive = FALSE; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enableNoiseReduction), noisesuppressActive); + g_signal_connect (G_OBJECT (enableNoiseReduction), "clicked", active_noise_suppress, NULL); + gtk_table_attach (GTK_TABLE (table), enableNoiseReduction, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); gtk_widget_show_all (ret); diff --git a/sflphone-client-gnome/src/config/preferencesdialog.c b/sflphone-client-gnome/src/config/preferencesdialog.c index 7aae7db058df4eeae98624b86cd838e4f1ff2ca3..03a93e2ee37ec184c9c5ef59e9488bf8b67ca3a2 100644 --- a/sflphone-client-gnome/src/config/preferencesdialog.c +++ b/sflphone-client-gnome/src/config/preferencesdialog.c @@ -32,22 +32,18 @@ */ #include <gtk/gtk.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <eel-gconf-extensions.h> -#include <accountlist.h> #include <accountconfigdialog.h> -#include <actions.h> -#include <config.h> -#include <dbus/dbus.h> -#include <mainwindow.h> -#include <audioconf.h> #include <addressbook-config.h> #include <shortcuts-config.h> +#include <audioconf.h> #include <hooks-config.h> -#include <utils.h> - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> +#include <audioconf.h> +#include <uimanager.h> /** * Local variables @@ -56,28 +52,37 @@ gboolean accDialogOpen = FALSE; gboolean dialogOpen = FALSE; gboolean ringtoneEnabled = TRUE; -GtkWidget * localPortSpinBox; -GtkWidget * localAddressCombo; - -GtkWidget * history_value; GtkWidget * status; +GtkWidget * history_value; -GtkWidget *showstatusicon; GtkWidget *starthidden; GtkWidget *popupwindow; GtkWidget *neverpopupwindow; -static int history_limit; -static gboolean history_enabled = TRUE; +GtkWidget *treeView; +GtkWidget *iconview; +GtkCellRenderer *renderer; +GtkTreeViewColumn *column; +GtkTreeSelection *selection; +GtkWidget * notebook; -static void -set_md5_hash_cb (GtkWidget *widget UNUSED, gpointer data UNUSED) -{ - gboolean enabled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); - dbus_set_md5_credential_hashing (enabled); -} +enum { + PIXBUF_COL, + TEXT_COL, + PAGE_NUMBER +}; + +typedef struct { + gchar* icon_descr; + gchar* icon_name; + gint page_number; +} browser_t; + + +static int history_limit; +static gboolean history_enabled = TRUE; static void start_hidden (void) @@ -87,7 +92,7 @@ start_hidden (void) } static void -set_popup_mode (GtkWidget *widget, gpointer *userdata) +set_popup_mode (GtkWidget *widget, gpointer *userdata UNUSED) { gboolean currentstate = eel_gconf_get_integer (POPUP_ON_CALL); @@ -104,7 +109,7 @@ set_notif_level () } static void -history_limit_cb (GtkSpinButton *button, void *ptr) +history_limit_cb (GtkSpinButton *button UNUSED, void *ptr) { history_limit = gtk_spin_button_get_value_as_int ( (GtkSpinButton *) (ptr)); } @@ -125,7 +130,7 @@ clean_history (void) calllist_clean_history (); } -void showstatusicon_cb (GtkWidget *widget, gpointer data) +void showstatusicon_cb (GtkWidget *widget, gpointer data UNUSED) { gboolean currentstatus = FALSE; @@ -149,7 +154,7 @@ GtkWidget* create_general_settings () { - GtkWidget *ret, *notifAll, *trayItem, *frame, *checkBoxWidget, *label, *table; + GtkWidget *ret, *notifAll, *frame, *checkBoxWidget, *label, *table, *showstatusicon; gboolean statusicon; // Load history configuration @@ -270,6 +275,35 @@ history_load_configuration () history_enabled = eel_gconf_get_integer (HISTORY_ENABLED); } + +void +selection_changed_cb (GtkIconView *view, gpointer user_data UNUSED) +{ + + GtkTreeModel *model; + GtkTreeIter iter; + GList *list; + gint page; + + model = gtk_icon_view_get_model (view); + list = gtk_icon_view_get_selected_items (view); + + if (list == NULL) + return; + + if (g_list_length (list) > 1) + return; + + gtk_tree_model_get_iter (model, &iter, list->data); + gtk_tree_model_get (model, &iter, PAGE_NUMBER, &page, -1); + + gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), page); + g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL); + g_list_free (list); +} + + + /** * Show configuration window with tabs */ @@ -277,7 +311,7 @@ void show_preferences_dialog () { GtkDialog * dialog; - GtkWidget * notebook; + GtkWidget * hbox; GtkWidget * tab; guint result; @@ -295,9 +329,27 @@ show_preferences_dialog () gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400); gtk_container_set_border_width (GTK_CONTAINER (dialog), 0); + hbox = gtk_hbox_new (FALSE, 10); + + // Create tree view + iconview = gtk_icon_view_new_with_model (createModel ()); + g_object_set (iconview, + "selection-mode", GTK_SELECTION_BROWSE, + "text-column", TEXT_COL, + "pixbuf-column", PIXBUF_COL, + "columns", 1, + "margin", 10, + NULL); + // Connect the callback when clicking on an item + g_signal_connect (G_OBJECT (iconview), "selection-changed", G_CALLBACK (selection_changed_cb), NULL); + gtk_box_pack_start (GTK_BOX (hbox), iconview, TRUE, TRUE, 0); + // Create tabs container notebook = gtk_notebook_new (); - gtk_box_pack_start (GTK_BOX (dialog->vbox), notebook, TRUE, TRUE, 0); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE); + gtk_box_pack_end (GTK_BOX (hbox), notebook, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (dialog->vbox), hbox, TRUE, TRUE, 0); + gtk_widget_show_all (dialog->vbox); gtk_container_set_border_width (GTK_CONTAINER (notebook), 10); gtk_widget_show (notebook); @@ -330,7 +382,10 @@ show_preferences_dialog () gtk_notebook_append_page (GTK_NOTEBOOK (notebook), tab, gtk_label_new (_ ("Shortcuts"))); gtk_notebook_page_num (GTK_NOTEBOOK (notebook), tab); + // By default, general settings gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 0); + // Highlight the corresponding icon + gtk_icon_view_select_path (GTK_ICON_VIEW (iconview), gtk_tree_path_new_first ()); result = gtk_dialog_run (dialog); @@ -342,3 +397,46 @@ show_preferences_dialog () gtk_widget_destroy (GTK_WIDGET (dialog)); } + +GtkTreeModel* createModel() +{ + + browser_t browser_entries[5] = { + {_ ("General"), "start-here", 0}, + {_ ("Audio"), "multimedia-volume-control", 1}, + {_ ("Address Book"), "address-book-new", 2}, + {_ ("Hooks"), "gnome-globe", 3}, + {_ ("Shortcuts"), "preferences-desktop-keyboard", 4} + }; + + GdkPixbuf *pixbuf; + GtkTreeIter iter; + GtkListStore *store; + GError *error = NULL; + gint i; + + store = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT); + GtkIconTheme* theme = gtk_icon_theme_get_default(); + + for (i = 0; i < 5; i++) { + + gtk_list_store_append (store, &iter); + + pixbuf = gtk_icon_theme_load_icon (theme, browser_entries[i].icon_name, 48, 0, &error); + + gtk_list_store_set (store, &iter, + PIXBUF_COL, pixbuf, + TEXT_COL, browser_entries[i].icon_descr, + PAGE_NUMBER, browser_entries[i].page_number, + -1); + + if (pixbuf != NULL) { + gdk_pixbuf_unref (pixbuf); + } else { + DEBUG ("Couldn't load icon: %s", error->message); + g_error_free (error); + } + } + + return GTK_TREE_MODEL (store); +} diff --git a/sflphone-client-gnome/src/config/preferencesdialog.h b/sflphone-client-gnome/src/config/preferencesdialog.h index fb5193bf70ac1bb8e7ad608eae116ebb92f4e097..c4a2a3f0be3036909f332490f96ab81afb8df3ed 100644 --- a/sflphone-client-gnome/src/config/preferencesdialog.h +++ b/sflphone-client-gnome/src/config/preferencesdialog.h @@ -121,4 +121,6 @@ void save_configuration_parameters (void); void history_load_configuration (void); +GtkTreeModel* createModel(); + #endif diff --git a/sflphone-client-gnome/src/config/shortcuts-config.c b/sflphone-client-gnome/src/config/shortcuts-config.c index 47fb054bd257f51bf9529654e7979980c04d2150..d57844f731af0a83ac4f32537a3b55ed120da449 100644 --- a/sflphone-client-gnome/src/config/shortcuts-config.c +++ b/sflphone-client-gnome/src/config/shortcuts-config.c @@ -33,46 +33,60 @@ #include <gdk/gdkx.h> -GtkWidget* -create_shortcuts_settings() +static void +accel_cleared (GtkCellRendererAccel *renderer UNUSED, gchar *path, + GtkTreeView *treeview) { - GtkWidget *vbox, *result_frame, *window, *treeview, *scrolled_window, *label; + DEBUG ("Accel cleared"); + GtkTreeModel *model; GtkTreeIter iter; - guint i = 0; - vbox = gtk_vbox_new (FALSE, 10); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 10); + // Update treeview + model = gtk_tree_view_get_model (treeview); - gnome_main_section_new (_ ("General"), &result_frame); + if (gtk_tree_model_get_iter_from_string (model, &iter, path)) + gtk_list_store_set (GTK_LIST_STORE (model), &iter, MASK, 0, VALUE, 0, -1); - label = gtk_label_new (_ ("Be careful: these shortcuts might override system-wide shortcuts.")); + // Update GDK bindings + shortcuts_update_bindings (atoi (path), 0, 0); +} - treeview = gtk_tree_view_new(); - setup_tree_view (treeview); +static void +accel_edited (GtkCellRendererAccel *renderer UNUSED, gchar *path, guint accel_key, + GdkModifierType mask, guint hardware_keycode UNUSED, GtkTreeView *treeview) +{ + DEBUG ("Accel edited"); - GtkListStore *store = gtk_list_store_new (COLUMNS, G_TYPE_STRING, G_TYPE_INT, G_TYPE_UINT); + GtkTreeModel *model; + GtkTreeIter iter; - Accelerator* list = shortcuts_get_list(); + Accelerator* list = shortcuts_get_list (); + model = gtk_tree_view_get_model (treeview); + guint code = XKeysymToKeycode (GDK_DISPLAY(), accel_key); + + // Disable existing binding if key already used + int i = 0; + gtk_tree_model_get_iter_first (model, &iter); while (list[i].action != NULL) { - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, ACTION, _ (list[i].action), MASK, - (gint) list[i].mask, VALUE, XKeycodeToKeysym (GDK_DISPLAY(), - list[i].value, 0), -1); + if (list[i].key == code && list[i].mask == mask) { + gtk_list_store_set (GTK_LIST_STORE (model), &iter, MASK, 0, VALUE, 0, + -1); + WARN ("This key was already affected"); + } + + gtk_tree_model_iter_next (model, &iter); i++; } - gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store)); - g_object_unref (store); - - gtk_container_add (GTK_CONTAINER (result_frame), treeview); - gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), result_frame, FALSE, FALSE, 0); - - gtk_widget_show_all (vbox); + // Update treeview + if (gtk_tree_model_get_iter_from_string (model, &iter, path)) + gtk_list_store_set (GTK_LIST_STORE (model), &iter, MASK, (gint) mask, + VALUE, accel_key, -1); - return vbox; + // Update GDK bindings + shortcuts_update_bindings (atoi (path), code, mask); } /* @@ -85,12 +99,12 @@ setup_tree_view (GtkWidget *treeview) GtkCellRenderer *renderer; GtkTreeViewColumn *column; - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes ("Action", renderer, "text", - ACTION, NULL); + renderer = gtk_cell_renderer_text_new (); + column = gtk_tree_view_column_new_with_attributes ("Action", renderer, + "text", ACTION, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); - renderer = gtk_cell_renderer_accel_new(); + renderer = gtk_cell_renderer_accel_new (); g_object_set (renderer, "accel-mode", GTK_CELL_RENDERER_ACCEL_MODE_GTK, "editable", TRUE, NULL); column = gtk_tree_view_column_new_with_attributes ("Shortcut", renderer, @@ -101,56 +115,46 @@ setup_tree_view (GtkWidget *treeview) g_signal_connect (G_OBJECT (renderer), "accel_cleared", G_CALLBACK (accel_cleared), (gpointer) treeview); } -static void -accel_edited (GtkCellRendererAccel *renderer, gchar *path, guint accel_key, - GdkModifierType mask, guint hardware_keycode, GtkTreeView *treeview) +GtkWidget* +create_shortcuts_settings () { - DEBUG ("Accel edited"); + GtkWidget *vbox, *result_frame, *treeview, *label; - GtkTreeModel *model; GtkTreeIter iter; + guint i = 0; - Accelerator* list = shortcuts_get_list(); - model = gtk_tree_view_get_model (treeview); - gint code = XKeysymToKeycode (GDK_DISPLAY(), accel_key); - - // Disable existing binding if key already used - int i = 0; - gtk_tree_model_get_iter_first (model, &iter); + vbox = gtk_vbox_new (FALSE, 10); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 10); - while (list[i].action != NULL) { - if (list[i].value == code) { - gtk_list_store_set (GTK_LIST_STORE (model), &iter, MASK, 0, VALUE, 0, -1); - WARN ("This key was already affected"); - } + gnome_main_section_new (_ ("General"), &result_frame); - gtk_tree_model_iter_next (model, &iter); - i++; - } + label = gtk_label_new ( + _ ("Be careful: these shortcuts might override system-wide shortcuts.")); + treeview = gtk_tree_view_new (); + setup_tree_view (treeview); - // Update treeview - if (gtk_tree_model_get_iter_from_string (model, &iter, path)) - gtk_list_store_set (GTK_LIST_STORE (model), &iter, MASK, (gint) mask, VALUE, - accel_key, -1); + GtkListStore *store = gtk_list_store_new (COLUMNS, G_TYPE_STRING, G_TYPE_INT, + G_TYPE_UINT); - // Update GDK bindings - shortcuts_update_bindings (atoi (path), code); -} + Accelerator* list = shortcuts_get_list (); -static void -accel_cleared (GtkCellRendererAccel *renderer, gchar *path, GtkTreeView *treeview) -{ - DEBUG ("Accel cleared"); + while (list[i].action != NULL) { + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, ACTION, _ (list[i].action), MASK, + (gint) list[i].mask, VALUE, XKeycodeToKeysym (GDK_DISPLAY(), + list[i].key, 0), -1); + i++; + } - GtkTreeModel *model; - GtkTreeIter iter; + gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (store)); + g_object_unref (store); - // Update treeview - model = gtk_tree_view_get_model (treeview); + gtk_container_add (GTK_CONTAINER (result_frame), treeview); + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), result_frame, FALSE, FALSE, 0); - if (gtk_tree_model_get_iter_from_string (model, &iter, path)) - gtk_list_store_set (GTK_LIST_STORE (model), &iter, MASK, 0, VALUE, 0, -1); + gtk_widget_show_all (vbox); - // Update GDK bindings - shortcuts_update_bindings (atoi (path), 0); + return vbox; } + diff --git a/sflphone-client-gnome/src/config/shortcuts-config.h b/sflphone-client-gnome/src/config/shortcuts-config.h index 10a4b85bfffb81c50dc50eb468bab733e0b8c09e..969ef27980bbb4d13c8f1882cf1cda54c92ee309 100644 --- a/sflphone-client-gnome/src/config/shortcuts-config.h +++ b/sflphone-client-gnome/src/config/shortcuts-config.h @@ -46,17 +46,6 @@ enum { GtkWidget* create_shortcuts_settings (); -static void -setup_tree_view (GtkWidget *treeview); - -static void -accel_edited (GtkCellRendererAccel *renderer, gchar *path, guint accel_key, - GdkModifierType mask, guint hardware_keycode, GtkTreeView *treeview); - -static void -accel_cleared (GtkCellRendererAccel *renderer, gchar *path, - GtkTreeView *treeview); - G_END_DECLS #endif // _SHORTCUTS_CONFIG diff --git a/sflphone-client-gnome/src/config/tlsadvanceddialog.c b/sflphone-client-gnome/src/config/tlsadvanceddialog.c index 530880d7957b23051f8c6deb910219a765f5eeab..05596dc27339ee75463516a5e8c71a38bb0fefc2 100644 --- a/sflphone-client-gnome/src/config/tlsadvanceddialog.c +++ b/sflphone-client-gnome/src/config/tlsadvanceddialog.c @@ -80,20 +80,20 @@ void show_advanced_tls_options (GHashTable * properties) gtk_label_set_markup (GTK_LABEL (label), description); gtk_table_attach (GTK_TABLE (table), label, 0, 3, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gchar * account_id; - gchar * tls_listener_port; - gchar * tls_ca_list_file; - gchar * tls_certificate_file; - gchar * tls_private_key_file; - gchar * tls_password; - gchar * tls_method; - gchar * tls_ciphers; - gchar * tls_server_name; - gchar * verify_server; - gchar * verify_client; - gchar * require_client_certificate; - gchar * negotiation_timeout_sec; - gchar * negotiation_timeout_msec; + gchar * account_id = NULL; + gchar * tls_listener_port = NULL; + gchar * tls_ca_list_file = NULL; + gchar * tls_certificate_file = NULL; + gchar * tls_private_key_file = NULL; + gchar * tls_password = NULL; + gchar * tls_method = NULL; + gchar * tls_ciphers = NULL; + gchar * tls_server_name = NULL; + gchar * verify_server = NULL; + gchar * verify_client = NULL; + gchar * require_client_certificate = NULL; + gchar * negotiation_timeout_sec = NULL; + gchar * negotiation_timeout_msec = NULL; if (properties != NULL) { diff --git a/sflphone-client-gnome/src/config/utils.c b/sflphone-client-gnome/src/config/utils.c index ded55acc62272e06b2bd6192e5bc6bab29e18532..66de3b7168f5f262678c6cc6420a1da6de16fc8e 100644 --- a/sflphone-client-gnome/src/config/utils.c +++ b/sflphone-client-gnome/src/config/utils.c @@ -29,6 +29,7 @@ */ #include "utils.h" +#include <sflphone_const.h> void gnome_main_section_new_with_table (gchar *title, GtkWidget **frame, GtkWidget **table, gint nb_col, gint nb_row) { @@ -63,7 +64,7 @@ void gnome_main_section_new_with_table (gchar *title, GtkWidget **frame, GtkWidg *frame = _frame; } -void gnome_main_section_new_with_vbox (gchar *title, GtkWidget **frame, GtkWidget **vbox, gint nb_row) +void gnome_main_section_new_with_vbox (gchar *title, GtkWidget **frame, GtkWidget **vbox, gint nb_row UNUSED) { GtkWidget *_frame, *_vbox, *label, *align; PangoAttrList *attrs = NULL; diff --git a/sflphone-client-gnome/src/config/zrtpadvanceddialog.c b/sflphone-client-gnome/src/config/zrtpadvanceddialog.c index 476565d2aead977d42cd642db65580961efd2f04..8d6594798f39d80a2fd7958bc345dda82ec0321e 100644 --- a/sflphone-client-gnome/src/config/zrtpadvanceddialog.c +++ b/sflphone-client-gnome/src/config/zrtpadvanceddialog.c @@ -38,7 +38,6 @@ void show_advanced_zrtp_options (GHashTable * properties) { GtkDialog * securityDialog; - GtkWidget * zrtpFrame; GtkWidget * tableZrtp; GtkWidget * enableHelloHash; GtkWidget * enableSASConfirm; diff --git a/sflphone-client-gnome/src/contacts/addressbook.c b/sflphone-client-gnome/src/contacts/addressbook.c index 0b38124c1df3840437de6448c455771bafaa24dd..a6d6a1fe8b4f42e82783e400b425d76cb3361b68 100644 --- a/sflphone-client-gnome/src/contacts/addressbook.c +++ b/sflphone-client-gnome/src/contacts/addressbook.c @@ -44,21 +44,18 @@ addressbook_search (GtkEntry* entry) { const gchar* query = gtk_entry_get_text (GTK_ENTRY (entry)); + DEBUG ("Addressbook: Search %s", query); - if (strlen (query) >= 3) { - AddressBook_Config *addressbook_config; + AddressBook_Config *addressbook_config; + + activateWaitingLayer(); - // Activate waiting layer - activateWaitingLayer(); + addressbook_config_load_parameters (&addressbook_config); - // Load the address book parameters - addressbook_config_load_parameters (&addressbook_config); - // Start the asynchronous search as soon as we have an entry */ - search_async (gtk_entry_get_text (GTK_ENTRY (entry)), addressbook_config->max_results, &handler_async_search, addressbook_config); + search_async_by_contacts (gtk_entry_get_text (GTK_ENTRY (entry)), addressbook_config->max_results, &handler_async_search, addressbook_config); - } } /** @@ -94,8 +91,7 @@ addressbook_is_active() } /** - * Asynchronous open callback. - * Used to handle activation of books. + * Get active addressbook from config. */ static void addressbook_config_books() @@ -116,17 +112,17 @@ addressbook_config_books() book_data = books_get_book_data_by_uid (*config_book_uid); // If book_data exists - if (book_data != NULL) { + if (!book_data) + ERROR ("Addressbook: Error: Could not open book"); - book_data->active = TRUE; - } + book_data->active = TRUE; } g_strfreev (list); } // Update buttons - update_actions (); + // update_actions (); } /** @@ -135,7 +131,11 @@ addressbook_config_books() GSList * addressbook_get_books_data() { + DEBUG ("Addressboook: Get books data"); + + fill_books_data(); addressbook_config_books(); + return books_data; } @@ -146,8 +146,13 @@ addressbook_get_books_data() void addressbook_init() { + DEBUG ("Addressbook: Initialize addressbook"); + + fill_books_data(); + addressbook_config_books(); + // Call books initialization - init (&addressbook_config_books); + init (); } /** @@ -162,6 +167,8 @@ handler_async_search (GList *hits, gpointer user_data) AddressBook_Config *addressbook_config; callable_obj_t *j; + DEBUG ("Addressbook: callback async search"); + // freeing calls while ( (j = (callable_obj_t *) g_queue_pop_tail (contacts->callQueue)) != NULL) { free_callable_obj_t (j); @@ -175,6 +182,7 @@ handler_async_search (GList *hits, gpointer user_data) calllist_reset (contacts); for (i = hits; i != NULL; i = i->next) { + Hit *entry; entry = i->data; @@ -210,5 +218,8 @@ handler_async_search (GList *hits, gpointer user_data) // Deactivate waiting image deactivateWaitingLayer(); + + + gtk_widget_grab_focus (GTK_WIDGET (contacts->view)); } diff --git a/sflphone-client-gnome/src/contacts/addressbook/eds.c b/sflphone-client-gnome/src/contacts/addressbook/eds.c index 6cb165d34bf6e91acd141bceb1b676d33b316ce5..0678e473abd111b78fbc133e69014206230eb6f6 100644 --- a/sflphone-client-gnome/src/contacts/addressbook/eds.c +++ b/sflphone-client-gnome/src/contacts/addressbook/eds.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Julien Bonjean <julien.bonjean@savoirfairelinux.com> + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> * * File originally copied from evolution module of deskbar-applet 2.24.1 * Authors : @@ -40,26 +41,19 @@ #include <string.h> #include <pango/pango.h> #include "eds.h" +#include <addressbook-config.h> /** * Structure used to store search callback and data */ typedef struct _Search_Handler_And_Data { - int search_id; - SearchAsyncHandler handler; + SearchAsyncHandler search_handler; gpointer user_data; GList *hits; int max_results_remaining; - int book_views_remaining; + EBookQuery *equery; } Search_Handler_And_Data; -/** - * Structure used to store open callback and data - */ -typedef struct _Open_Handler_And_Data { - OpenAsyncHandler handler; -} Open_Handler_And_Data; - /** * Size of image that will be displayed in contact list */ @@ -71,11 +65,13 @@ static int pixbuf_size = 32; int remaining_books_to_open; /** - * Fields on which search will be performed + * Current selected addressbook's uri and uid, initialized with default */ -static EContactField search_fields[] = { E_CONTACT_FULL_NAME, E_CONTACT_PHONE_BUSINESS, E_CONTACT_NICKNAME, 0 }; +static gchar *current_uri = NULL; +static gchar *current_uid = NULL; +static gchar *current_name = "Default"; -static int n_search_fields = G_N_ELEMENTS (search_fields) - 1; +static EBookQueryTest current_test = E_BOOK_QUERY_BEGINS_WITH; /** * Freeing a hit instance @@ -129,100 +125,54 @@ books_get_book_data_by_uid (gchar *uid) GSList *book_list_iterator; book_data_t *book_data; + DEBUG ("Addressbook: Get book data by uid: %s", uid); + // Iterate throw the list for (book_list_iterator = books_data; book_list_iterator != NULL; book_list_iterator = book_list_iterator->next) { book_data = (book_data_t *) book_list_iterator->data; - if (strcmp (book_data->uid, uid) == 0) + if (strcmp (book_data->uid, uid) == 0) { + DEBUG ("Addressbook: Book %s found", uid); return book_data; + } } + DEBUG ("Addressbook: Could not found Book %s", uid); // If no result return NULL; } -/** - * Split a string of tokens separated by whitespace into an array of tokens. - */ -static GArray * -split_query_string (const gchar *str) -{ - GArray *parts = g_array_sized_new (FALSE, FALSE, sizeof (char *), 2); - PangoLogAttr *attrs; - guint str_len = strlen (str), word_start = 0, i; - - attrs = g_new0 (PangoLogAttr, str_len + 1); - /* TODO: do we need to specify a particular language or is NULL ok? */ - pango_get_log_attrs (str, -1, -1, NULL, attrs, str_len + 1); - - for (i = 0; i < str_len + 1; i++) { - char *start_word, *end_word, *word; - - if (attrs[i].is_word_end) { - start_word = g_utf8_offset_to_pointer (str, word_start); - end_word = g_utf8_offset_to_pointer (str, i); - word = g_strndup (start_word, end_word - start_word); - g_array_append_val (parts, word); - } - - if (attrs[i].is_word_start) { - word_start = i; - } - } - - g_free (attrs); - return parts; -} /** * Create a query which looks for the specified string in a contact's full name, email addresses and * nick name. */ static EBookQuery* -create_query (const char* s) +create_query (const char* s, EBookQueryTest test, AddressBook_Config *conf) { - EBookQuery *query; - GArray *parts = split_query_string (s); - EBookQuery ***field_queries; - EBookQuery **q; - EBookQuery **phone; - guint j; - int i; - - q = g_new0 (EBookQuery *, n_search_fields); - field_queries = g_new0 (EBookQuery **, n_search_fields); - - for (i = 0; i < n_search_fields; i++) { - field_queries[i] = g_new0 (EBookQuery *, parts->len); - - for (j = 0; j < parts->len; j++) { - field_queries[i][j] = e_book_query_field_test (search_fields[i], - E_BOOK_QUERY_CONTAINS, g_array_index (parts, gchar *, j)); - } - q[i] = e_book_query_and (parts->len, field_queries[i], TRUE); - } + EBookQuery *equery; + EBookQuery *queries[4]; - g_array_free (parts, TRUE); + // Create the query + int cpt = 0; - phone = g_new0 (EBookQuery *, 3); - phone[0] = e_book_query_field_exists (E_CONTACT_PHONE_BUSINESS); - phone[1] = e_book_query_field_exists (E_CONTACT_PHONE_HOME); - phone[2] = e_book_query_field_exists (E_CONTACT_PHONE_MOBILE); + // We could also use E_BOOK_QUERY_IS or E_BOOK_QUERY_BEGINS_WITH instead of E_BOOK_QUERY_CONTAINS + queries[cpt++] = e_book_query_field_test (E_CONTACT_FULL_NAME, test, s); - query = e_book_query_andv (e_book_query_or (n_search_fields, q, FALSE), - e_book_query_or (3, phone, FALSE), NULL); + if (conf->search_phone_home) + queries[cpt++] = e_book_query_field_test (E_CONTACT_PHONE_HOME, test, s); - for (i = 0; i < n_search_fields; i++) { - g_free (field_queries[i]); - } + if (conf->search_phone_business) + queries[cpt++] = e_book_query_field_test (E_CONTACT_PHONE_BUSINESS, test, s); + + if (conf->search_phone_mobile) + queries[cpt++] = e_book_query_field_test (E_CONTACT_PHONE_MOBILE, test, s); - g_free (field_queries); - g_free (q); - g_free (phone); + equery = e_book_query_or (cpt, queries, TRUE); - return query; + return equery; } /** @@ -275,282 +225,411 @@ pixbuf_from_contact (EContact *contact) } /** - * Callback for asynchronous open of books + * Final callback after all books have been processed. */ static void -eds_async_open_callback (EBook *book, EBookStatus status, gpointer closure) +view_finish_callback (EBookView *book_view, Search_Handler_And_Data *had) { - Open_Handler_And_Data *had = (Open_Handler_And_Data *) closure; - - remaining_books_to_open--; + SearchAsyncHandler had_handler = had->search_handler; + GList *had_hits = had->hits; + gpointer had_user_data = had->user_data; - DEBUG ("eds_async_open_callback remaining book to open: %i", remaining_books_to_open); + g_free (had); - if (status == E_BOOK_ERROR_OK) { + DEBUG ("Addressbook: View finish"); - book_data_t *book_data = g_new (book_data_t, 1); - book_data->active = FALSE; - book_data->name = g_strdup (e_source_peek_name (e_book_get_source (book))); - book_data->uid = g_strdup (e_source_peek_uid (e_book_get_source (book))); - book_data->ebook = book; - books_data = g_slist_prepend (books_data, book_data); - had->handler(); - } else { + if (book_view != NULL) + g_object_unref (book_view); - WARN ("Got error %d when opening book", status); - } + // Call display callback + had_handler (had_hits, had_user_data); } + /** - * Initialize address book + * Callback called after a contact have been found in EDS by search_async_by_contacts. */ -void -init (OpenAsyncHandler callback) +static void +eds_query_result_cb (EBook *book, EBookStatus status, GList *contacts, gpointer user_data) { - GSList *list, *l; - ESourceList *source_list = NULL; - remaining_books_to_open = 0; - books_data = NULL; - source_list = e_source_list_new_for_gconf_default ("/apps/evolution/addressbook/sources"); + DEBUG ("Addressbook: Search Result callback called"); - if (source_list == NULL) { - DEBUG ("Error could not initialize source list for addressbook"); + if (status != E_BOOK_ERROR_OK) + ERROR ("Addressbook: Error: Status not OK on search callback"); + + Search_Handler_And_Data *had = (Search_Handler_And_Data *) user_data; + + if (!contacts) { + DEBUG ("Addressbook: No contact found"); + had->search_handler (NULL, user_data); return; } - list = e_source_list_peek_groups (source_list); + GList *l = NULL; - Open_Handler_And_Data *had = g_new (Open_Handler_And_Data, 1); - had->handler = callback; + if (status == E_BOOK_ERROR_OK) { - for (l = list; l != NULL; l = l->next) { + gchar *number; - ESourceGroup *group = l->data; - GSList *sources = NULL, *m; - sources = e_source_group_peek_sources (group); + // make sure we have a new list of hits + had->hits = NULL; - for (m = sources; m != NULL; m = m->next) { - ESource *source = m->data; - EBook *book = e_book_new (source, NULL); + l = contacts; + + while (l) { + + Hit *hit = g_new (Hit, 1); + + if (hit) { + + // Get the photo contact + hit->photo = pixbuf_from_contact (E_CONTACT (l->data)); + + // Get business phone information + fetch_information_from_contact (E_CONTACT (l->data), E_CONTACT_PHONE_BUSINESS, &number); + hit->phone_business = g_strdup (number); + + // Get home phone information + fetch_information_from_contact (E_CONTACT (l->data), E_CONTACT_PHONE_HOME, &number); + hit->phone_home = g_strdup (number); - if (book != NULL) { - // Keep count of remaining books to open + // Get mobile phone information + fetch_information_from_contact (E_CONTACT (l->data), E_CONTACT_PHONE_MOBILE, &number); + hit->phone_mobile = g_strdup (number); - DEBUG ("init addressbook %i", remaining_books_to_open); - remaining_books_to_open++; + hit->name = g_strdup ( (char *) e_contact_get_const (E_CONTACT (l->data), E_CONTACT_NAME_OR_ORG)); - // Asynchronous open - e_book_async_open (book, FALSE, eds_async_open_callback, had); + if (!hit->name) + hit->name = ""; + + /* + DEBUG ("Addressbook: Contact Found"); + DEBUG ("Addressbook: Full Name %s", hit->name); + DEBUG ("Addressbook: Phone Home %s", hit->phone_home); + DEBUG ("Addressbook: Phone Business %s", hit->phone_business); + DEBUG ("Addressbook: Phone Mobile %s", hit->phone_mobile); + */ + + if (hit) + had->hits = g_list_append (had->hits, hit); + + + // DEBUG ("Addressbook: max_result_remaining %d", had->max_results_remaining); + had->max_results_remaining--; + + if (had->max_results_remaining <= 0) + break; } + + l = g_list_next (l); + } + + view_finish_callback (NULL, had); } - current_search_id = 0; + g_object_unref (book); - g_object_unref (source_list); } + + /** - * Final callback after all books have been processed. + * Callback for asynchronous open of books */ static void -view_finish (EBookView *book_view, Search_Handler_And_Data *had) +eds_async_open_callback (EBook *book, EBookStatus status, gpointer closure) { - GList *i; - SearchAsyncHandler had_handler = had->handler; - GList *had_hits = had->hits; - gpointer had_user_data = had->user_data; - int search_id = had->search_id; - g_free (had); + DEBUG ("Addressbook: Open book callback"); - if (book_view != NULL) - g_object_unref (book_view); + Search_Handler_And_Data *had = (Search_Handler_And_Data *) closure; + + if (status == E_BOOK_ERROR_OK) { + + if (!e_book_is_opened (book)) { + // We must open the addressbook + e_book_open (book, FALSE, NULL); + } - if (search_id == current_search_id) { - // Reinitialize search id to prevent overflow - if (current_search_id > 5000) - current_search_id = 0; + if (e_book_async_get_contacts (book, had->equery, eds_query_result_cb, had)) + ERROR ("Addressbook: Error: While querying addressbook"); - // Call display callback - had_handler (had_hits, had_user_data); } else { - // Some hits could have been processed but will not be used - for (i = had_hits; i != NULL; i = i->next) { - Hit *entry; - entry = i->data; - free_hit (entry); + WARN ("Addressbook: Got error when opening book"); + gchar *state_string = NULL; + + switch (status) { + case E_BOOK_ERROR_INVALID_ARG : + state_string = g_strdup ("E_BOOK_ERROR_INVALID_ARG"); + break; + case E_BOOK_ERROR_BUSY : + state_string = g_strdup ("E_BOOK_ERROR_BUSY"); + break; + case E_BOOK_ERROR_REPOSITORY_OFFLINE : + state_string = g_strdup ("E_BOOK_ERROR_REPOSITORY_OFFLINE"); + break; + case E_BOOK_ERROR_NO_SUCH_BOOK : + state_string = g_strdup ("E_BOOK_ERROR_NO_SUCH_BOOK"); + break; + case E_BOOK_ERROR_NO_SELF_CONTACT : + state_string = g_strdup ("E_BOOK_ERROR_NO_SELF_CONTACT"); + break; + case E_BOOK_ERROR_SOURCE_NOT_LOADED: + state_string = g_strdup ("E_BOOK_ERROR_SOURCE_NOT_LOADED"); + break; + case E_BOOK_ERROR_SOURCE_ALREADY_LOADED : + state_string = g_strdup ("E_BOOK_ERROR_SOURCE_ALREADY_LOADED"); + break; + case E_BOOK_ERROR_PERMISSION_DENIED : + state_string = g_strdup ("E_BOOK_ERROR_PERMISSION_DENIED"); + break; + case E_BOOK_ERROR_CONTACT_NOT_FOUND : + state_string = g_strdup ("E_BOOK_ERROR_CONTACT_NOT_FOUND"); + break; + case E_BOOK_ERROR_CONTACT_ID_ALREADY_EXISTS : + state_string = g_strdup ("E_BOOK_ERROR_CONTACT_ID_ALREADY_EXISTS"); + break; + case E_BOOK_ERROR_PROTOCOL_NOT_SUPPORTED : + state_string = g_strdup ("E_BOOK_ERROR_PROTOCOL_NOT_SUPPORTED"); + break; + case E_BOOK_ERROR_CANCELLED : + state_string = g_strdup ("E_BOOK_ERROR_CANCELLED"); + break; + case E_BOOK_ERROR_COULD_NOT_CANCEL : + state_string = g_strdup ("E_BOOK_ERROR_COULD_NOT_CANCEL"); + break; + case E_BOOK_ERROR_AUTHENTICATION_FAILED : + state_string = g_strdup ("E_BOOK_ERROR_AUTHENTICATION_FAILED"); + break; + case E_BOOK_ERROR_AUTHENTICATION_REQUIRED : + state_string = g_strdup ("E_BOOK_ERROR_AUTHENTICATION_REQUIRED"); + break; + case E_BOOK_ERROR_TLS_NOT_AVAILABLE : + state_string = g_strdup ("E_BOOK_ERROR_TLS_NOT_AVAILABLE"); + break; + case E_BOOK_ERROR_CORBA_EXCEPTION : + state_string = g_strdup ("E_BOOK_ERROR_CORBA_EXCEPTION"); + break; + case E_BOOK_ERROR_NO_SUCH_SOURCE : + state_string = g_strdup ("E_BOOK_ERROR_NO_SUCH_SOURCE"); + break; + case E_BOOK_ERROR_OFFLINE_UNAVAILABLE : + state_string = g_strdup ("E_BOOK_ERROR_OFFLINE_UNAVAILABLE"); + break; + case E_BOOK_ERROR_OTHER_ERROR : + state_string = g_strdup ("E_BOOK_ERROR_OTHER_ERROR"); + break; + case E_BOOK_ERROR_INVALID_SERVER_VERSION : + state_string = g_strdup ("E_BOOK_ERROR_INVALID_SERVER_VERSION"); + break; + default: + break; + } - g_list_free (had_hits); + ERROR ("%s", state_string); + + g_free (state_string); } + } /** - * Callback called after each ebook search completed. - * Used to store book search results. + * Initialize address book */ -static void -view_contacts_added_cb (EBookView *book_view, GList *contacts, - gpointer user_data) +void +init () { - GdkPixbuf *photo; + GError *err = NULL; + gchar *absuri, *reluri; - Search_Handler_And_Data *had = (Search_Handler_And_Data *) user_data; + EBook *default_addressbook = e_book_new_default_addressbook (&err); - // If it's not the last search launched, stop it - if (had->search_id != current_search_id) { - e_book_view_stop (book_view); - return; - } + if (err) + ERROR ("Addressbook: Error: Could not create new book from source: %s", err->message); - // If we reached max results - if (had->max_results_remaining <= 0) { - e_book_view_stop (book_view); - had->book_views_remaining--; + ESource *default_source = e_book_get_source (default_addressbook); - // All books have been computed - if (had->book_views_remaining == 0) { - view_finish (book_view, had); - return; - } - } + // DEBUG ("Addressbook: Default source relative uri %s", e_source_peek_relative_uri (default_source)); + // DEBUG ("Addressbook: Default source absolute uri %s", e_source_peek_absolute_uri (default_source)); - // For each contact - for (; contacts != NULL; contacts = g_list_next (contacts)) { - EContact *contact; - Hit *hit; - gchar *number; + if (current_uri) { + g_free (current_uri); + current_uri = NULL; + } - contact = E_CONTACT (contacts->data); - hit = g_new (Hit, 1); + if (current_uid) { + g_free (current_uid); + current_uid = NULL; + } - // Get the photo contact - photo = pixbuf_from_contact (contact); - hit->photo = photo; + if (strcmp (current_name, "Default") != 0) { + g_free (current_name); + current_name = NULL; + } - // Get business phone information - fetch_information_from_contact (contact, E_CONTACT_PHONE_BUSINESS, &number); - hit->phone_business = g_strdup (number); + // TODO: This should work but return a NULL pointer ... + // if (! (group = e_source_peek_group (default_source))); - // Get home phone information - fetch_information_from_contact (contact, E_CONTACT_PHONE_HOME, &number); - hit->phone_home = g_strdup (number); + // ERROR ("Addressbook: Error: No group found for default addressbook"); - // Get mobile phone information - fetch_information_from_contact (contact, E_CONTACT_PHONE_MOBILE, &number); - hit->phone_mobile = g_strdup (number); + absuri = g_strdup (e_source_peek_absolute_uri (default_source)); + // absuri = g_strdup (e_source_group_peek_base_uri (group)); + reluri = g_strdup (e_source_peek_relative_uri (default_source)); - hit->name = g_strdup ( (char*) e_contact_get_const (contact, - E_CONTACT_NAME_OR_ORG)); + if (!absuri) { + absuri = g_malloc (1); + *absuri = 0; + } - if (!hit->name) - hit->name = ""; + if (!reluri) { + reluri = g_malloc (1); + *reluri = 0; + } - // Append list of contacts - had->hits = g_list_append (had->hits, hit); - had->max_results_remaining--; + // Do not overwrite current_name for default + // current_name = g_strdup (e_source_peek_name (default_source)); - // If we reached max results - if (had->max_results_remaining <= 0) { - e_book_view_stop (book_view); - had->book_views_remaining--; + current_uid = g_strdup (e_source_peek_uid (default_source)); - if (had->book_views_remaining == 0) { - view_finish (book_view, had); - } + if (strcmp (absuri+strlen (absuri)-1, "/") == 0) + current_uri = g_strjoin ("", absuri, reluri, NULL); + else + current_uri = g_strjoin ("/", absuri, reluri, NULL); - break; - } - } + g_free (absuri); + g_free (reluri); } + /** - * Callback called after each ebook search completed. - * Used to call final callback when all books have been read. + * Fill book data */ -static void -view_completed_cb (EBookView *book_view, EBookViewStatus status UNUSED, - gpointer user_data) +void +fill_books_data () { - Search_Handler_And_Data *had = (Search_Handler_And_Data *) user_data; - had->book_views_remaining--; + GSList *list, *l; + ESourceList *source_list = NULL; + remaining_books_to_open = 0; + books_data = NULL; + + source_list = e_source_list_new_for_gconf_default ("/apps/evolution/addressbook/sources"); + + if (source_list == NULL) { + ERROR ("Addressbook: Error could not initialize source list for addressbook"); + return; + } + + list = e_source_list_peek_groups (source_list); + + if (!list) { + ERROR ("Addressbook: Address Book source groups are missing! Check your GConf setup."); + return; + } + + + for (l = list; l != NULL; l = l->next) { + + ESourceGroup *group = l->data; + GSList *sources = NULL, *m; + gchar *absuri; + + absuri = g_strdup (e_source_group_peek_base_uri (group)); + + sources = e_source_group_peek_sources (group); + + for (m = sources; m != NULL; m = m->next) { + + ESource *source = m->data; + + book_data_t *book_data = g_new (book_data_t, 1); + book_data->active = FALSE; + book_data->name = g_strdup (e_source_peek_name (source)); + book_data->uid = g_strdup (e_source_peek_uid (source)); + + gchar *prop = e_source_get_property (source, "default"); + + if (prop) + if (strcmp (prop, "true") == 0) + book_data->isdefault = TRUE; + else + book_data->isdefault = FALSE; + else + book_data->isdefault = FALSE; + + if (strcmp (absuri+strlen (absuri)-1, "/") == 0) + book_data->uri = g_strjoin ("", absuri, e_source_peek_relative_uri (source), NULL); + else + book_data->uri = g_strjoin ("/", absuri, e_source_peek_relative_uri (source), NULL); + + books_data = g_slist_prepend (books_data, book_data); - // All books have been prcessed - if (had->book_views_remaining == 0) { - // Call finish function - view_finish (book_view, had); + } + + g_free (absuri); } + + g_object_unref (source_list); } -/** - * Perform an asynchronous search - */ void -search_async (const char *query, int max_results, SearchAsyncHandler handler, - gpointer user_data) +search_async_by_contacts (const char *query, int max_results, SearchAsyncHandler handler, gpointer user_data) { - // Increment search id - current_search_id++; + GError *err = NULL; + EBook *book; - // If query is null - if (strlen (query) < 1 || g_slist_length (books_data) == 0) { - // If data displayed (from previous search), directly call callback - handler (NULL, user_data); + DEBUG ("Addressbook: New search by contacts: %s, max_results %d", query, max_results); + if (strlen (query) < 1) { + DEBUG ("Addressbook: Query is empty"); + handler (NULL, user_data); return; } - GSList *iter; - EBookQuery* book_query = create_query (query); Search_Handler_And_Data *had = g_new (Search_Handler_And_Data, 1); - int search_count = 0; - // Initialize search data - had->search_id = current_search_id; - had->handler = handler; + // initialize search data + had->search_handler = handler; had->user_data = user_data; had->hits = NULL; had->max_results_remaining = max_results; - had->book_views_remaining = 0; - - // Iterate throw books data - for (iter = books_data; iter != NULL; iter = iter->next) { - book_data_t *book_data = (book_data_t *) iter->data; - - // If book is active - if (book_data->active) { - EBookView *book_view = NULL; - e_book_get_book_view (book_data->ebook, book_query, NULL, max_results, - &book_view, NULL); - - // If book view exists - if (book_view != NULL) { - // Perform search - had->book_views_remaining++; - g_signal_connect (book_view, "contacts_added", (GCallback) view_contacts_added_cb, had); - g_signal_connect (book_view, "sequence_complete", (GCallback) view_completed_cb, had); - e_book_view_start (book_view); - search_count++; - } - } - } + had->equery = create_query (query, current_test, (AddressBook_Config *) (user_data)); + + if (!current_uri) + ERROR ("Addressbook: Error: Current addressbook uri not specified uri"); + + + DEBUG ("Addressbook: Opening addressbook: %s", current_uri); + DEBUG ("Addressbook: Opening addressbook: %s", current_name); + + // TODO: This hack is necessary as we cannot access group's base_uri of the default book + // see init() + + if (strcmp (current_name, "Default") == 0) + book = e_book_new_default_addressbook (&err); + else + book = e_book_new_from_uri (current_uri, &err); + + if (err) + ERROR ("Addressbook: Error: Could not open new book: %s", err->message); + + if (book) { + DEBUG ("Addressbook: Created empty book successfully"); + + // Asynchronous open + e_book_async_open (book, TRUE, eds_async_open_callback, had); + } else + ERROR ("Addressbook: Error: No book available"); - e_book_query_unref (book_query); - // If no search has been executed (no book selected) - if (search_count == 0) { - // Call last callback anyway - view_finish (NULL, had); - } } /** * Fetch information for a specific contact */ void -fetch_information_from_contact (EContact *contact, EContactField field, - gchar **info) +fetch_information_from_contact (EContact *contact, EContactField field, gchar **info) { gchar *to_fetch; @@ -563,3 +642,42 @@ fetch_information_from_contact (EContact *contact, EContactField field, *info = g_strdup (to_fetch); } +void +set_current_addressbook (const gchar *name) +{ + + GSList *book_list_iterator; + book_data_t *book_data; + + // Iterate throw the list + for (book_list_iterator = books_data; book_list_iterator != NULL; book_list_iterator + = book_list_iterator->next) { + book_data = (book_data_t *) book_list_iterator->data; + + if (strcmp (book_data->name, name) == 0) { + current_uri = book_data->uri; + current_uid = book_data->uid; + current_name = book_data->name; + } + } +} + + +const gchar * +get_current_addressbook (void) +{ + return current_name; +} + + +void +set_current_addressbook_test (EBookQueryTest test) +{ + current_test = test; +} + +EBookQueryTest +get_current_addressbook_test (void) +{ + return current_test; +} diff --git a/sflphone-client-gnome/src/contacts/addressbook/eds.h b/sflphone-client-gnome/src/contacts/addressbook/eds.h index 2e44756a9ae962aae343729882e200912838322a..51b8421c9b25080cdaa7d47671f2af865259bcbd 100644 --- a/sflphone-client-gnome/src/contacts/addressbook/eds.h +++ b/sflphone-client-gnome/src/contacts/addressbook/eds.h @@ -43,6 +43,7 @@ #include <libebook/e-book.h> #include <sflphone_const.h> + #define EMPTY_ENTRY "empty" G_BEGIN_DECLS @@ -69,9 +70,10 @@ typedef struct _Hit { */ typedef struct { gchar *uid; + gchar *uri; gchar *name; gboolean active; - EBook *ebook; + gboolean isdefault; } book_data_t; GSList *books_data; @@ -99,14 +101,19 @@ typedef void * Connection to evolution data server */ void -init (OpenAsyncHandler); +init (); + +/** + * Fill list of addressbooks + */ +void +fill_books_data (void); /** - * Asynchronous search function + * Asynchronous query to EDS using get contact method. */ void -search_async (const char *query, int max_results, SearchAsyncHandler handler, - gpointer user_data); +search_async_by_contacts (const char *query, int max_results, SearchAsyncHandler handler, gpointer user_data); /** * Retrieve the specified information from the contact @@ -139,6 +146,25 @@ books_active(); GSList * addressbook_get_books_data(); +/** + * Set the current address book + */ +void +set_current_addressbook (const gchar *name); + +/** + * Return current addressbook name + */ +const gchar * +get_current_addressbook (void); + +void +set_current_addressbook_test (EBookQueryTest test); + +EBookQueryTest +get_current_addressbook_test (void); + + G_END_DECLS #endif /* __EDS_H__ */ diff --git a/sflphone-client-gnome/src/contacts/calllist.c b/sflphone-client-gnome/src/contacts/calllist.c index ead96bbc2eaec2955fdbad2646b054166ca97096..5211a6cd4c6a78e92848dd3967be03e50c0cbcd5 100644 --- a/sflphone-client-gnome/src/contacts/calllist.c +++ b/sflphone-client-gnome/src/contacts/calllist.c @@ -31,6 +31,7 @@ #include <calllist.h> #include <calltree.h> #include <contacts/searchbar.h> +#include <eel-gconf-extensions.h> // TODO : sflphoneGTK : try to do this more generic void calllist_add_contact (gchar *contact_name, gchar *contact_phone, contact_type_t type, GdkPixbuf *photo) @@ -113,13 +114,13 @@ calllist_clean_history (void) { unsigned int i; guint size = calllist_get_size (history); - DEBUG ("history list size = %i", calllist_get_size (history)); + DEBUG ("CallList: history list size = %i", calllist_get_size (history)); for (i = 0 ; i < size ; i++) { - DEBUG ("Delete calls"); + DEBUG ("CallList: Delete calls"); callable_obj_t* c = calllist_get_nth (history , i); // Delete the call from the call tree - DEBUG ("Delete calls"); + DEBUG ("CallList: Delete calls"); calltree_remove_call (history, c, NULL); } @@ -132,7 +133,7 @@ calllist_remove_from_history (callable_obj_t* c) { calllist_remove (history, c->_callID); calltree_remove_call (history, c, NULL); - DEBUG ("Size of history = %i" , calllist_get_size (history)); + DEBUG ("CallList: Size of history = %i" , calllist_get_size (history)); } void diff --git a/sflphone-client-gnome/src/contacts/calltree.c b/sflphone-client-gnome/src/contacts/calltree.c index 5b90c5553f64aafc85de1446dfc1eda365fb080c..d6e4a0341fde7142d8cb9298fd5d96fcff7b69cd 100644 --- a/sflphone-client-gnome/src/contacts/calltree.c +++ b/sflphone-client-gnome/src/contacts/calltree.c @@ -33,10 +33,13 @@ #include <calltree.h> #include <stdlib.h> #include <glib/gprintf.h> +#include <eel-gconf-extensions.h> #include <calllist.h> #include <conferencelist.h> #include <mainwindow.h> #include <history.h> +#include "uimanager.h" +#include "actions.h" GtkWidget *sw; GtkCellRenderer *rend; @@ -74,7 +77,6 @@ enum { COLUMN_ACCOUNT_PTR, }; - /** * Show popup menu */ @@ -235,15 +237,16 @@ row_activated (GtkTreeView *tree_view UNUSED, if (selectedConf) { switch (selectedConf->_state) { - case CONFERENCE_STATE_ACTIVE_ATACHED: - // sflphone_add_main_participant(selectedConf); - break; case CONFERENCE_STATE_ACTIVE_DETACHED: sflphone_add_main_participant (selectedConf); break; case CONFERENCE_STATE_HOLD: sflphone_conference_off_hold (selectedConf); break; + case CONFERENCE_STATE_ACTIVE_ATACHED: + case CONFERENCE_STATE_RECORD: + default: + break; } } } @@ -342,11 +345,10 @@ button_pressed (GtkWidget* widget, GdkEventButton *event, gpointer user_data UNU } -gchar* -calltree_display_call_info (callable_obj_t * c, CallDisplayType display_type, gchar *audio_codec, gchar** display_info) +void calltree_display_call_info (callable_obj_t * c, CallDisplayType display_type, gchar *audio_codec, gchar** display_info) { - gchar * description; + gchar * description = NULL; gchar * tmp_info; gchar * peer_number = c->_peer_number; @@ -413,7 +415,7 @@ calltree_display_call_info (callable_obj_t * c, CallDisplayType display_type, gc case DISPLAY_TYPE_CALL_TRANSFER: - DEBUG ("CallTree: Display a call transfer") + DEBUG ("CallTree: Display a call transfer"); if (g_strcmp0 ("",c->_peer_name) == 0) { description = g_markup_printf_escaped ("<b>%s</b><i>%s</i>\n<i>Transfert to:%s</i> ", @@ -490,7 +492,6 @@ calltree_display_call_info (callable_obj_t * c, CallDisplayType display_type, gc } - // return description; tmp_info = g_strdup (description); *display_info = tmp_info; } @@ -509,16 +510,12 @@ calltree_reset (calltab_t* tab) void focus_on_calltree_out() { - //DEBUG("set_focus_on_calltree_out"); - // gtk_widget_grab_focus(GTK_WIDGET(sw)); focus_is_on_calltree = FALSE; } void focus_on_calltree_in() { - //DEBUG("set_focus_on_calltree_in"); - // gtk_widget_grab_focus(GTK_WIDGET(sw)); focus_is_on_calltree = TRUE; } @@ -567,9 +564,6 @@ calltree_create (calltab_t* tab, gboolean searchbar_type) G_CALLBACK (button_pressed), NULL); - // g_signal_connect (G_OBJECT (sw), "key-release-event", - // G_CALLBACK (on_key_released), NULL); - g_signal_connect_after (G_OBJECT (tab->view), "focus-in-event", G_CALLBACK (focus_on_calltree_in), NULL); g_signal_connect_after (G_OBJECT (tab->view), "focus-out-event", @@ -683,6 +677,8 @@ calltree_remove_call (calltab_t* tab, callable_obj_t * c, GtkTreeIter *parent) update_actions(); + calltree_update_clock(); + DEBUG ("Calltre remove call ended"); } @@ -698,7 +694,6 @@ calltree_update_call (calltab_t* tab, callable_obj_t * c, GtkTreeIter *parent) gchar* srtp_enabled = ""; gboolean display_sas = TRUE; - gboolean sdes_success = TRUE; account_t* account_details=NULL; gchar *audio_codec = ""; @@ -899,8 +894,6 @@ void calltree_add_call (calltab_t* tab, callable_obj_t * c, GtkTreeIter *parent) // New call in the list gchar * description; - gchar * date=""; - gchar *duration=""; calltree_display_call_info (c, DISPLAY_TYPE_CALL, NULL, &description); @@ -915,7 +908,7 @@ void calltree_add_call (calltab_t* tab, callable_obj_t * c, GtkTreeIter *parent) } } - DEBUG ("Added call key exchange is %s", key_exchange) + DEBUG ("Added call key exchange is %s", key_exchange); if (tab == current_calls) { switch (c->_state) { @@ -1273,12 +1266,9 @@ void calltree_add_conference (calltab_t* tab, conference_obj_t* conf) } -void calltree_update_conference (calltab_t* tab, const gchar* confID) +void calltree_update_conference (calltab_t* tab UNUSED, const gchar* confID UNUSED) { - DEBUG ("calltree_update_conference"); - - } @@ -1417,16 +1407,43 @@ void calltree_display (calltab_t *tab) } +void calltree_update_clock() +{ + callable_obj_t *c = calltab_get_selected_call (current_calls); -static void drag_begin_cb (GtkWidget *widget, GdkDragContext *dc, gpointer data) -{ + // if(!selected_call) { + if (!c) { + statusbar_update_clock (""); + return; + } + + // if(!(selected_call->_timestr)) { + if (! (c->_timestr)) { + statusbar_update_clock (""); + return; + } + + if ( (c->_state != CALL_STATE_INVALID) && + (c->_state != CALL_STATE_INCOMING) && + (c->_state != CALL_STATE_RINGING) && + (c->_state != CALL_STATE_DIALING) && + (c->_state != CALL_STATE_FAILURE) && + (c->_state != CALL_STATE_BUSY)) { + + // TODO this make the whole thing crash... + statusbar_update_clock (c->_timestr); + } else { + statusbar_update_clock (""); + } +} - GtkTargetList* target_list; +static void drag_begin_cb (GtkWidget *widget UNUSED, GdkDragContext *dc UNUSED, gpointer data UNUSED) +{ } -static void drag_end_cb (GtkWidget * widget, GdkDragContext * context, gpointer data) +static void drag_end_cb (GtkWidget * widget UNUSED, GdkDragContext * context UNUSED, gpointer data UNUSED) { DEBUG ("CallTree: Drag end callback"); DEBUG ("CallTree: selected_path %s, selected_call_id %s, selected_path_depth %d", @@ -1440,13 +1457,10 @@ static void drag_end_cb (GtkWidget * widget, GdkDragContext * context, gpointer GtkTreePath *spath = gtk_tree_path_new_from_string (selected_path); GtkTreeIter iter; - GtkTreeIter iter_parent; - GtkTreeIter iter_children; GtkTreeIter parent_conference; // conference for which this call is attached GValue val; - callable_obj_t* call; conference_obj_t* conf; @@ -1696,21 +1710,16 @@ static void drag_end_cb (GtkWidget * widget, GdkDragContext * context, gpointer } -void drag_data_received_cb (GtkWidget *widget, GdkDragContext *context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint t, gpointer data) +void drag_data_received_cb (GtkWidget *widget, GdkDragContext *context UNUSED, gint x UNUSED, gint y UNUSED, GtkSelectionData *selection_data UNUSED, guint info UNUSED, guint t UNUSED, gpointer data UNUSED) { - - // DEBUG("drag_data_received_cb\n"); GtkTreeView *tree_view = GTK_TREE_VIEW (widget); GtkTreePath *drop_path; GtkTreeViewDropPosition position; GValue val; - GtkTreeModel *model = (GtkTreeModel*) active_calltree->store; GtkTreeModel* tree_model = gtk_tree_view_get_model (tree_view); GtkTreeIter iter; - gchar value; - val.g_type = 0; gtk_tree_view_get_drag_dest_row (tree_view, &drop_path, &position); diff --git a/sflphone-client-gnome/src/contacts/calltree.h b/sflphone-client-gnome/src/contacts/calltree.h index d94d741bbb70a7be7c65fdbf34a3d18442f8eadf..04f50cf46c494de2bfd727ed955f9514ce1b9b09 100644 --- a/sflphone-client-gnome/src/contacts/calltree.h +++ b/sflphone-client-gnome/src/contacts/calltree.h @@ -111,4 +111,10 @@ calltree_display (calltab_t *tab); void row_activated (GtkTreeView *, GtkTreePath *, GtkTreeViewColumn *, void *); +/** + * Update elapced time based on selected calltree's call + */ +void +calltree_update_clock(); + #endif diff --git a/sflphone-client-gnome/src/contacts/history.c b/sflphone-client-gnome/src/contacts/history.c index 3a11a70f0f2e2b2f0bf8f219ea123726fac046bd..9853b5b2bb76ac857327652bafc7420234e3c1b5 100644 --- a/sflphone-client-gnome/src/contacts/history.c +++ b/sflphone-client-gnome/src/contacts/history.c @@ -39,7 +39,7 @@ GtkWidget * history_searchbar_widget; static GtkTreeModel* history_create_filter (GtkTreeModel*); static gboolean history_is_visible (GtkTreeModel*, GtkTreeIter*, gpointer); -void history_search (SearchType search_type) +void history_search (SearchType search_type UNUSED) { if (history_filter != NULL) { gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (history_filter)); @@ -108,7 +108,7 @@ static gboolean history_is_visible (GtkTreeModel* model, GtkTreeIter* iter, gpoi return g_regex_match_simple (search, text, G_REGEX_CASELESS, 0); else { // We need a match on the history_state_t and the current search type - return (history_entry->_history_state + 1) == (int) get_current_history_search_type () && + return (history_entry->_history_state + 1) == (guint) get_current_history_search_type () && g_regex_match_simple (search, text, G_REGEX_CASELESS, 0); } } diff --git a/sflphone-client-gnome/src/contacts/searchbar.c b/sflphone-client-gnome/src/contacts/searchbar.c index eec22e53011b822c0af323d84c72efcf99e4f20b..db416d659c1ebec6a4e7f09033ec88c660cf9397 100644 --- a/sflphone-client-gnome/src/contacts/searchbar.c +++ b/sflphone-client-gnome/src/contacts/searchbar.c @@ -33,8 +33,15 @@ #include <searchbar.h> #include <calltree.h> +#include <contacts/addressbook/eds.h> GtkWidget * searchbox; +GtkWidget * addressbookentry; + +GtkWidget * cbox; +GtkListStore * liststore; + +gint cboxSignalId; static GtkWidget *menu = NULL; @@ -45,20 +52,110 @@ GdkPixbuf *incoming_pixbuf = NULL; GdkPixbuf *outgoing_pixbuf = NULL; GdkPixbuf *missed_pixbuf = NULL; -void searchbar_entry_changed (GtkEntry* entry, gchar* arg1 UNUSED, gpointer data UNUSED) + + +void searchbar_addressbook_activated (GtkEntry *entry, gchar *arg1 UNUSED, gpointer data UNUSED) { - DEBUG ("searchbar_entry_changed"); + DEBUG ("Searchbar: Entry activated"); + + addressbook_search (entry); +} + +void searchbar_entry_changed (GtkEntry* entry UNUSED, gchar* arg1 UNUSED, gpointer data UNUSED) +{ + DEBUG ("Searchbar: Entry changed"); if (active_calltree == contacts) { - addressbook_search (entry); + // Search made only when text entry is activated + // addressbook_search (entry); } else if (active_calltree == history) { history_search (HistorySearchType); } } -#if GTK_CHECK_VERSION(2,16,0) +static void cbox_changed_cb (GtkWidget *widget, gpointer user_data UNUSED) +{ + gchar *name; -static void search_all (GtkWidget *item, GtkEntry *entry) + name = gtk_combo_box_get_active_text (GTK_COMBO_BOX (widget)); + + set_current_addressbook (name); + + addressbook_search (GTK_ENTRY (addressbookentry)); +} + +void update_searchbar_addressbook_list() +{ + gint count; + GtkTreeIter iter, activeIter; + gchar *activeText; + GSList *book_list_iterator; + book_data_t *book_data; + GSList *books_data = addressbook_get_books_data(); + + // we must disconnect signal from teh cbox while updating its content + gtk_signal_disconnect (cbox, cboxSignalId); + + // store the current active text + activeText = g_strdup (gtk_combo_box_get_active_text (GTK_COMBO_BOX (cbox))); + + gtk_list_store_clear (liststore); + + // Populate menu + count = 0; + gboolean activeIsSet = FALSE; + + for (book_list_iterator = books_data; book_list_iterator != NULL; book_list_iterator + = book_list_iterator->next) { + book_data = (book_data_t *) book_list_iterator->data; + + if (book_data->active) { + + gtk_list_store_append (liststore, &iter); + gtk_list_store_set (liststore, &iter, 0, book_data->name, -1); + + if (strcmp (book_data->name, activeText) == 0) { + activeIter = iter; + activeIsSet = TRUE; + } + + count++; + } + } + + if (activeIsSet) + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (cbox), &activeIter); + else + gtk_combo_box_set_active (GTK_COMBO_BOX (cbox), 0); + + g_free (activeText); + cboxSignalId = gtk_signal_connect (GTK_OBJECT (cbox), "changed", G_CALLBACK (cbox_changed_cb), NULL); +} + + +static void select_search_type (GtkWidget *item, GtkEntry *entry UNUSED) +{ + DEBUG ("Searchbar: %s", gtk_menu_item_get_label (GTK_MENU_ITEM (item))); + + + + gtk_entry_set_icon_tooltip_text (GTK_ENTRY (addressbookentry), GTK_ENTRY_ICON_PRIMARY, + gtk_menu_item_get_label (GTK_MENU_ITEM (item))); + + + if (strcmp ("Search is", gtk_menu_item_get_label (GTK_MENU_ITEM (item))) == 0) + set_current_addressbook_test (E_BOOK_QUERY_IS); + else if (strcmp ("Search begins with", gtk_menu_item_get_label (GTK_MENU_ITEM (item))) == 0) + set_current_addressbook_test (E_BOOK_QUERY_BEGINS_WITH); + else if (strcmp ("Search contains", gtk_menu_item_get_label (GTK_MENU_ITEM (item))) == 0) + set_current_addressbook_test (E_BOOK_QUERY_CONTAINS); + + addressbook_search (GTK_ENTRY (addressbookentry)); + + +} + +static void search_all (GtkWidget *item UNUSED, GtkEntry *entry) { HistorySearchType = SEARCH_ALL; @@ -71,7 +168,7 @@ static void search_all (GtkWidget *item, GtkEntry *entry) history_search (HistorySearchType); } -static void search_by_missed (GtkWidget *item, GtkEntry *entry) +static void search_by_missed (GtkWidget *item UNUSED, GtkEntry *entry) { HistorySearchType = SEARCH_MISSED; @@ -83,7 +180,7 @@ static void search_by_missed (GtkWidget *item, GtkEntry *entry) history_search (HistorySearchType); } -static void search_by_incoming (GtkWidget *item, GtkEntry *entry) +static void search_by_incoming (GtkWidget *item UNUSED, GtkEntry *entry) { HistorySearchType = SEARCH_INCOMING; @@ -95,7 +192,7 @@ static void search_by_incoming (GtkWidget *item, GtkEntry *entry) history_search (HistorySearchType); } -static void search_by_outgoing (GtkWidget *item, GtkEntry *entry) +static void search_by_outgoing (GtkWidget *item UNUSED, GtkEntry *entry) { HistorySearchType = SEARCH_OUTGOING; @@ -107,16 +204,22 @@ static void search_by_outgoing (GtkWidget *item, GtkEntry *entry) history_search (HistorySearchType); } -static void icon_press_cb (GtkEntry *entry, gint position, GdkEventButton *event, gpointer data) +static void icon_press_cb (GtkEntry *entry, gint position, GdkEventButton *event, gpointer data UNUSED) { + DEBUG ("Searchbar: Icon pressed"); + if (position == GTK_ENTRY_ICON_PRIMARY && active_calltree == history) gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, event->button, event->time); - else + else if (position == GTK_ENTRY_ICON_PRIMARY && active_calltree == contacts) { + GtkWidget *addrbook_menu = addressbook_menu_new(); + gtk_menu_popup (GTK_MENU (addrbook_menu), NULL, NULL, NULL, NULL, + event->button, event->time); + } else gtk_entry_set_text (entry, ""); } -static void text_changed_cb (GtkEntry *entry, GParamSpec *pspec) +static void text_changed_cb (GtkEntry *entry, GParamSpec *pspec UNUSED) { gboolean has_text; @@ -124,7 +227,34 @@ static void text_changed_cb (GtkEntry *entry, GParamSpec *pspec) gtk_entry_set_icon_sensitive (entry, GTK_ENTRY_ICON_SECONDARY, has_text); } -#endif + + +GtkWidget *addressbook_menu_new (void) +{ + + GtkWidget *menu, *item; + + // Create the menu + menu = gtk_menu_new (); + gtk_menu_attach_to_widget (GTK_MENU (menu), contacts->searchbar, NULL); + + // Populate menu + item = gtk_menu_item_new_with_label ("Search is"); + g_signal_connect (item, "activate", G_CALLBACK (select_search_type), searchbox); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_menu_item_new_with_label ("Search begins with"); + g_signal_connect (item, "activate", G_CALLBACK (select_search_type), searchbox); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_menu_item_new_with_label ("Search contains"); + g_signal_connect (item, "activate", G_CALLBACK (select_search_type), searchbox); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + gtk_widget_show_all (menu); + + return menu; +} void focus_on_searchbar_out() @@ -231,46 +361,108 @@ GtkWidget* contacts_searchbar_new () { GtkWidget *ret; + GtkWidget *align; + int count, cbox_height, cbox_width; + GtkTreeIter iter, activeIter; + GtkCellRenderer *cell; ret = gtk_hbox_new (FALSE, 0); + liststore = gtk_list_store_new (1,G_TYPE_STRING); + + // Create combo box to select current addressbook + + GSList *book_list_iterator; + book_data_t *book_data; + GSList *books_data = addressbook_get_books_data(); + + // Populate menu + count = 0; + gboolean activeIsSet = FALSE; + + for (book_list_iterator = books_data; book_list_iterator != NULL; book_list_iterator + = book_list_iterator->next) { + book_data = (book_data_t *) book_list_iterator->data; + + if (book_data->active) { + + gtk_list_store_append (liststore, &iter); + gtk_list_store_set (liststore, &iter, 0, book_data->name, -1); + + if (book_data->isdefault) { + activeIter = iter; + activeIsSet = TRUE; + } + + count++; + } + } + + cbox = gtk_combo_box_new_with_model ( (GtkTreeModel *) liststore); + + if (activeIsSet) + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (cbox), &activeIter); + else + gtk_combo_box_set_active (GTK_COMBO_BOX (cbox), 0); + + align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); + gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 2, 6, 6); + gtk_container_add (GTK_CONTAINER (align), cbox); + + gtk_widget_get_size_request (GTK_WIDGET (cbox), &cbox_width, &cbox_height); + gtk_widget_set_size_request (GTK_WIDGET (cbox), cbox_width, 26); + + cboxSignalId = gtk_signal_connect (GTK_OBJECT (cbox), "changed", G_CALLBACK (cbox_changed_cb), NULL); + + cell = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (cbox), cell, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (cbox), cell, "text", 0, NULL); + #if GTK_CHECK_VERSION(2,16,0) - GdkPixbuf *pixbuf; + // GdkPixbuf *pixbuf; - searchbox = gtk_entry_new(); - gtk_entry_set_icon_from_stock (GTK_ENTRY (searchbox), GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR); - pixbuf = gdk_pixbuf_new_from_file (ICONS_DIR "/stock_person.svg", NULL); - gtk_entry_set_icon_from_pixbuf (GTK_ENTRY (searchbox), GTK_ENTRY_ICON_PRIMARY, pixbuf); - gtk_entry_set_icon_tooltip_text (GTK_ENTRY (searchbox), GTK_ENTRY_ICON_PRIMARY, - "Search contacts\n" - "GNOME evolution backend"); + gchar *tooltip_text = g_strdup ("Search is"); + + addressbookentry = gtk_entry_new(); + gtk_entry_set_icon_from_stock (GTK_ENTRY (addressbookentry), GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR); + // pixbuf = gdk_pixbuf_new_from_file (ICONS_DIR "/stock_person.svg", NULL); + gtk_entry_set_icon_from_stock (GTK_ENTRY (addressbookentry), GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_FIND); + gtk_entry_set_icon_tooltip_text (GTK_ENTRY (addressbookentry), GTK_ENTRY_ICON_PRIMARY, + tooltip_text); // Set the clean insensitive - text_changed_cb (GTK_ENTRY (searchbox), NULL); + text_changed_cb (GTK_ENTRY (addressbookentry), NULL); - g_signal_connect (searchbox, "notify::text", G_CALLBACK (text_changed_cb), NULL); - g_signal_connect (searchbox, "icon-press", G_CALLBACK (icon_press_cb), NULL); + g_signal_connect (addressbookentry, "notify::text", G_CALLBACK (text_changed_cb), NULL); + g_signal_connect (addressbookentry, "icon-press", G_CALLBACK (icon_press_cb), NULL); #else GtkWidget *image; - searchbox = sexy_icon_entry_new(); + addressbookentry = sexy_icon_entry_new(); image = gtk_image_new_from_stock (GTK_STOCK_FIND , GTK_ICON_SIZE_SMALL_TOOLBAR); - sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (searchbox), SEXY_ICON_ENTRY_PRIMARY , GTK_IMAGE (image)); - sexy_icon_entry_add_clear_button (SEXY_ICON_ENTRY (searchbox)); + sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (addressbookentry), SEXY_ICON_ENTRY_PRIMARY , GTK_IMAGE (image)); + sexy_icon_entry_add_clear_button (SEXY_ICON_ENTRY (addressbookentry)); #endif - g_signal_connect_after (GTK_ENTRY (searchbox), "changed", G_CALLBACK (searchbar_entry_changed), NULL); + gtk_entry_set_activates_default (GTK_ENTRY (addressbookentry), TRUE); + g_signal_connect_after (GTK_ENTRY (addressbookentry), "activate", G_CALLBACK (searchbar_addressbook_activated), NULL); - g_signal_connect_after (G_OBJECT (searchbox), "focus-in-event", + g_signal_connect_after (GTK_ENTRY (addressbookentry), "changed", G_CALLBACK (searchbar_entry_changed), NULL); + + g_signal_connect_after (G_OBJECT (addressbookentry), "focus-in-event", G_CALLBACK (focus_on_searchbar_in), NULL); - g_signal_connect_after (G_OBJECT (searchbox), "focus-out-event", + g_signal_connect_after (G_OBJECT (addressbookentry), "focus-out-event", G_CALLBACK (focus_on_searchbar_out), NULL); - gtk_box_pack_start (GTK_BOX (ret), searchbox, TRUE, TRUE, 0); + + gtk_box_pack_start (GTK_BOX (ret), align, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (ret), addressbookentry, TRUE, TRUE, 0); + + g_free (tooltip_text); return ret; } @@ -289,3 +481,4 @@ SearchType get_current_history_search_type (void) { return HistorySearchType; } + diff --git a/sflphone-client-gnome/src/contacts/searchbar.h b/sflphone-client-gnome/src/contacts/searchbar.h index 0fa107cce7fd48f3b82d74b9f97c45fa3ca8cb4d..91f32d0f78df364481d5292a96c24af347cf1d48 100644 --- a/sflphone-client-gnome/src/contacts/searchbar.h +++ b/sflphone-client-gnome/src/contacts/searchbar.h @@ -81,4 +81,11 @@ void activateWaitingLayer(); */ void deactivateWaitingLayer(); +/** + * Reload combo box to update list of active addressbook + */ +void update_searchbar_addressbook_list (void); + +GtkWidget *addressbook_menu_new (void); + #endif diff --git a/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml b/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml old mode 100644 new mode 100755 index f75d22c662e8b34451ef22540ec124e3c7f25b08..c2818831f9e18520fe3bbfbe9c0982bd6a2133a2 --- a/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml +++ b/sflphone-client-gnome/src/dbus/configurationmanager-introspec.xml @@ -101,29 +101,15 @@ </arg> </method> - <method name="setNumberOfCredential" tp:name-for-bindings="setNumberOfCredential"> + <method name="deleteAllCredential" tp:name-for-bindings="deleteAllCredential"> <tp:docstring> </tp:docstring> <arg type="s" name="accountID" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - <arg type="i" name="number" direction="in"> <tp:docstring> </tp:docstring> </arg> </method> - <method name="deleteAllCredential" tp:name-for-bindings="deleteAllCredential"> - <tp:docstring> - </tp:docstring> - <arg type="s" name="accountID" direction="in"> - <tp:docstring> - Account ID - </tp:docstring> - </arg> - </method> - <method name="getIp2IpDetails" tp:name-for-bindings="getIp2IpDetails"> <tp:docstring> Get configuration settings of the IP2IP_PROFILE. They are sligthly different from account settings since no VoIP accounts are involved. @@ -207,55 +193,55 @@ <method name="addAccount" tp:name-for-bindings="addAccount"> <tp:docstring> - Add a new account. When created, the signal <tp:member-ref>accountsChanged</tp:member-ref> is emitted. The clients must then call <tp:member-ref>getAccountList</tp:member-ref> to update their internal data structure. - <tp:rationale>If no details are specified, the default parameters are used.</tp:rationale> - <tp:rationale>The core tries to register the account as soon it is created.</tp:rationale> + Add a new account. When created, the signal <tp:member-ref>accountsChanged</tp:member-ref> is emitted. The clients must then call <tp:member-ref>getAccountList</tp:member-ref> to update their internal data structure. + <tp:rationale>If no details are specified, the default parameters are used.</tp:rationale> + <tp:rationale>The core tries to register the account as soon it is created.</tp:rationale> </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="MapStringString"/> <arg type="a{ss}" name="details" direction="in" tp:type="String_String_Map"> - <tp:docstring> - The new account settings - </tp:docstring> + <tp:docstring> + The new account settings + </tp:docstring> </arg> <arg type="s" name="createdAccountId" direction="out"> - <tp:docstring> - A new account ID - </tp:docstring> + <tp:docstring> + A new account ID + </tp:docstring> </arg> </method> <method name="setAccountsOrder" tp:name-for-bindings="setAccountsOrder"> <tp:docstring> - Update the accounts order. - <tp:rationale>When placing a call, the first registered account in the list is used.</tp:rationale> + Update the accounts order. + <tp:rationale>When placing a call, the first registered account in the list is used.</tp:rationale> </tp:docstring> <arg type="s" name="order" direction="in"> - <tp:docstring> - An ordered list of account IDs, delimited by '/' - </tp:docstring> + <tp:docstring> + An ordered list of account IDs, delimited by '/' + </tp:docstring> </arg> </method> <method name="removeAccount" tp:name-for-bindings="removeAccount"> - <tp:docstring> - Remove an existing account. When removed, the signal <tp:member-ref>accountsChanged</tp:member-ref> is emitted. The clients must then call <tp:member-ref>getAccountList</tp:member-ref> to update their internal data structure. - </tp:docstring> - <arg type="s" name="accoundID" direction="in"> - <tp:docstring> - The account to remove, identified by its ID - </tp:docstring> - </arg> + <tp:docstring> + Remove an existing account. When removed, the signal <tp:member-ref>accountsChanged</tp:member-ref> is emitted. The clients must then call <tp:member-ref>getAccountList</tp:member-ref> to update their internal data structure. + </tp:docstring> + <arg type="s" name="accoundID" direction="in"> + <tp:docstring> + The account to remove, identified by its ID + </tp:docstring> + </arg> </method> <method name="getAccountList" tp:name-for-bindings="getAccountList"> - <tp:docstring> - Get a list of all created accounts, as stored by the core. - </tp:docstring> + <tp:docstring> + Get a list of all created accounts, as stored by the core. + </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> - <tp:docstring> - A list of account IDs - </tp:docstring> + <tp:docstring> + A list of account IDs + </tp:docstring> </arg> </method> @@ -268,15 +254,15 @@ @param[in] input accountID --> <arg type="s" name="accountID" direction="in"> - <tp:docstring> - The account ID - </tp:docstring> + <tp:docstring> + The account ID + </tp:docstring> </arg> <arg type="i" name="expire" direction="in"> - <tp:docstring> - <p>To register, expire must be 1.</p> - <p>To un-register, expire must be 0.</p> - </tp:docstring> + <tp:docstring> + <p>To register, expire must be 1.</p> + <p>To un-register, expire must be 0.</p> + </tp:docstring> </arg> </method> @@ -285,14 +271,13 @@ </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> - <tp:docstring> - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getVersion" tp:name-for-bindings="getVersion"> <tp:docstring> - Return SFLphone-daemon version </tp:docstring> <arg type="s" name="version" direction="out"> <tp:docstring> @@ -302,19 +287,16 @@ <method name="getRingtoneList" tp:name-for-bindings="getRingtoneList"> <tp:docstring> - Return a list of valid Sun's .au sound file used - as ringtones. </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> - <tp:docstring> - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getPlaybackDeviceList" tp:name-for-bindings="getPlaybackDeviceList"> <tp:docstring> - Provide a list of playback device from ALSA </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> @@ -325,7 +307,6 @@ <method name="getRecordDeviceList" tp:name-for-bindings="getRecordDeviceList"> <tp:docstring> - Provide a list of record device from ALSA </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> @@ -336,8 +317,8 @@ <method name="isRingtoneEnabled" tp:name-for-bindings="isRingtoneEnabled"> <tp:docstring> - Return true if ringtone is enabled, false otherwise </tp:docstring> + <arg type="s" name="accountID" direction="in" /> <arg type="i" name="bool" direction="out"> <tp:docstring> </tp:docstring> @@ -346,28 +327,27 @@ <method name="ringtoneEnabled" tp:name-for-bindings="ringtoneEnabled"> <tp:docstring> - Unused </tp:docstring> + <arg type="s" name="accountID" direction="in"/> </method> <method name="getRingtoneChoice" tp:name-for-bindings="getRingtoneChoice"> <tp:docstring> - Get current ringtone .au file selected </tp:docstring> + <arg type="s" name="accountID" direction="in"/> <arg type="s" name="tone" direction="out"> - <tp:docstring> - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="setRingtoneChoice" tp:name-for-bindings="setRingtoneChoice"> <tp:docstring> - Set current ringtone .au file from list acquired using <tp:member-ref>getAccountList</tp:member-ref> </tp:docstring> + <arg type="s" name="accountID" direction="in"/> <arg type="s" name="tone" direction="in"> - <tp:docstring> - A valid .au file path - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> @@ -476,16 +456,7 @@ </arg> </method> - <method name="setInputAudioPlugin" tp:name-for-bindings="setInputAudioPlugin"> - <tp:docstring> - </tp:docstring> - <arg type="s" name="audioPlugin" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setOutputAudioPlugin" tp:name-for-bindings="setOutputAudioPlugin"> + <method name="setAudioPlugin" tp:name-for-bindings="setAudioPlugin"> <tp:docstring> </tp:docstring> <arg type="s" name="audioPlugin" direction="in"> @@ -633,20 +604,6 @@ </arg> </method> - <method name="setNotify" tp:name-for-bindings="setNotify"> - <tp:docstring> - </tp:docstring> - </method> - - <method name="getNotify" tp:name-for-bindings="getNotify"> - <tp:docstring> - </tp:docstring> - <arg type="i" name="level" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - <method name="setMailNotify" tp:name-for-bindings="setMailNotify"> <tp:docstring> </tp:docstring> @@ -661,69 +618,6 @@ </arg> </method> - <method name="getDialpad" tp:name-for-bindings="getDialpad"> - <tp:docstring> - </tp:docstring> - <arg type="i" name="state" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setDialpad" tp:name-for-bindings="setDialpad"> - <tp:docstring> - </tp:docstring> - <arg type="b" name="display" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="getSearchbar" tp:name-for-bindings="getSearchbar"> - <tp:docstring> - </tp:docstring> - <arg type="i" name="state" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setSearchbar" tp:name-for-bindings="setSearchbar"> - <tp:docstring> - </tp:docstring> - </method> - - <method name="setHistoryEnabled" tp:name-for-bindings="setHistoryEnabled"> - <tp:docstring> - </tp:docstring> - </method> - - <method name="getHistoryEnabled" tp:name-for-bindings="getHistoryEnabled"> - <tp:docstring> - </tp:docstring> - <arg type="s" name="state" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="getVolumeControls" tp:name-for-bindings="getVolumeControls"> - <tp:docstring> - </tp:docstring> - <arg type="i" name="state" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setVolumeControls" tp:name-for-bindings="setVolumeControls"> - <tp:docstring> - </tp:docstring> - <arg type="b" name="display" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - </method> <method name="getHistoryLimit" tp:name-for-bindings="getHistoryLimit"> <tp:docstring> @@ -743,137 +637,6 @@ </arg> </method> - <method name="startHidden" tp:name-for-bindings="startHidden"> - <tp:docstring> - </tp:docstring> - </method> - - <method name="isStartHidden" tp:name-for-bindings="isStartHidden"> - <tp:docstring> - </tp:docstring> - <arg type="i" name="state" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="popupMode" tp:name-for-bindings="popupMode"> - <tp:docstring> - </tp:docstring> - <arg type="i" name="state" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="switchPopupMode" tp:name-for-bindings="switchPopupMode"> - <tp:docstring> - </tp:docstring> - </method> - - <method name="getWindowWidth" tp:name-for-bindings="getWindowWidth"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="width" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="getWindowHeight" tp:name-for-bindings="getWindowHeight"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="height" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setWindowWidth" tp:name-for-bindings="setWindowWidth"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="width" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setWindowHeight" tp:name-for-bindings="setWindowHeight"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="height" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="getWindowPositionX" tp:name-for-bindings="getWindowPositionX"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="posX" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setWindowPositionX" tp:name-for-bindings="setWindowPositionX"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="posX" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="getWindowPositionY" tp:name-for-bindings="getWindowPositionY"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="posY" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setWindowPositionY" tp:name-for-bindings="setWindowPositionY"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="posY" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="enableStatusIcon" tp:name-for-bindings="enableStatusIcon"> - <tp:docstring> - Allow SFLphone icon to be displayed in system tray - </tp:docstring> - <arg type="s" name="value" direction="in"> - <tp:docstring> - true/false - </tp:docstring> - </arg> - </method> - - <method name="isStatusIconEnabled" tp:name-for-bindings="isStatusIconEnabled"> - <tp:docstring> - Test if SFLphone icon is displayed in system tray. - </tp:docstring> - <arg type="s" name="value" direction="out"> - <tp:docstring> - true/false - </tp:docstring> - </arg> - </method> - - <!-- Addressbook configuration --> <method name="getAddressbookSettings" tp:name-for-bindings="getAddressbookSettings"> <tp:docstring> @@ -952,162 +715,110 @@ </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="MapStringString"/> <arg type="a{ss}" name="entries" direction="in"> - <tp:docstring> - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <signal name="accountsChanged" tp:name-for-bindings="accountsChanged"> - <tp:docstring> - Signal emited on account changes. Clients should update - all account status with <tp:member-ref>getAccountDetails</tp:member-ref> - iterating over the list provided by <tp:member-ref>getAccountList</tp:member-ref> - </tp:docstring> </signal> <signal name="errorAlert" tp:name-for-bindings="errorAlert"> <arg type="i" name="code"> - <tp:docstring> - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </signal> <!-- TLS Methods --> <method name="getSupportedTlsMethod" tp:name-for-bindings="getSupportedTlsMethod"> <tp:docstring> - Provide a list of supported TLS method </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> - <tp:docstring> - A list of TLS method: (TLSv1, SSLv1, SSLv2, - SSLv3, SSLv23) - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getTlsSettingsDefault" tp:name-for-bindings="getTlsSettingsDefault"> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/> <tp:docstring> - Get default TLS setting for new accounts </tp:docstring> <arg type="a{ss}" name="details" direction="out"> - <tp:docstring> - A hash table containing details. Refer - to <tp:member-ref>getTlsSettings</tp:member-ref> - for possible keys - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getTlsSettings" tp:name-for-bindings="getTlsSettings"> <tp:docstring> - Get current TLS setting for a specific account </tp:docstring> - <arg type="s" name="accountID" direction="in"> - <tp:docstring> - The account ID - </tp:docstring> - </arg> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/> <arg type="a{ss}" name="details" direction="out"> - <tp:docstring> - A hash table containing details with key: - <ul> - <li>"TLS.listenerPort": valid numerical port</li> - <li>"TLS.enable": true/false</li> - <li>"TLS.certificateListFile": A valid path to - a .pem file containing CA certificate</li> - <li>"TLS.certificateFile": A valid path to a - file containing the public end-point - certificate (optional)</li> - <li>"TLS.privateKeyFile": A valid path to a - file containing the public end-point private - key (optional)</li> - <li>"TLS.password": Public end-point private - key password (optional)</li> - <li>"TLS.method": (TLSv1, SSLv1, SSLv2, - SSLv3, SSLv23)</li> - </ul> - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="setTlsSettings" tp:name-for-bindings="setTlsSettings"> <tp:docstring> - Update TLS setting for a specific account </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="MapStringString"/> - <arg type="s" name="accountID" direction="in"> - <tp:docstring> - The account ID - </tp:docstring> - </arg> <arg type="a{ss}" name="details" direction="in"> - <tp:docstring> - A hash table containing details. Refer - to <tp:member-ref>getTlsSettings</tp:member-ref> - for possible keys. - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getAddrFromInterfaceName" tp:name-for-bindings="getAddrFromInterfaceName"> <tp:docstring> - Resolve interface IPv4 address provided its name. </tp:docstring> <arg type="s" name="interface" direction="in"> - <tp:docstring> - Interface name - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> <arg type="s" name="address" direction="out"> - <tp:docstring> - Interface IPv4 address - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getAllIpInterface" tp:name-for-bindings="getAllIpInterface"> <tp:docstring> - Provide a list of IP interface's IPv4 address. </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> - <tp:docstring> - A list of interface's IPv4 address - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getAllIpInterfaceByName" tp:name-for-bindings="getAllIpInterfaceByName"> <tp:docstring> - Provide a list of IP interface's name: default - (0.0.0.0), lo, eth0 ... </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> - <tp:docstring> - A list of interface's name - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getShortcuts" tp:name-for-bindings="getShortcuts"> - <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringInt"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/> <tp:docstring> </tp:docstring> - <arg type="a{si}" name="shortcutsMap" direction="out"> + <arg type="a{ss}" name="shortcutsMap" direction="out"> <tp:docstring> </tp:docstring> </arg> </method> <method name="setShortcuts" tp:name-for-bindings="setShortcuts"> - <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="MapStringInt"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="MapStringString"/> <tp:docstring> </tp:docstring> - <arg type="a{si}" name="shortcutsMap" direction="in"> + <arg type="a{ss}" name="shortcutsMap" direction="in"> <tp:docstring> </tp:docstring> </arg> diff --git a/sflphone-client-gnome/src/dbus/dbus.c b/sflphone-client-gnome/src/dbus/dbus.c index f1284db9450fbe237daebb26672dfeccb6602938..4313a1df9a6fc9e6521215b0248e2087d5dd4788 100644 --- a/sflphone-client-gnome/src/dbus/dbus.c +++ b/sflphone-client-gnome/src/dbus/dbus.c @@ -96,11 +96,9 @@ zrtp_negotiation_failed_cb (DBusGProxy *proxy UNUSED, const gchar* callID, } static void -curent_selected_codec (DBusGProxy *proxy UNUSED, const gchar* callID, - const gchar* codecName, void * foo UNUSED) +curent_selected_codec (DBusGProxy *proxy UNUSED, const gchar* callID UNUSED, + const gchar* codecName UNUSED, void * foo UNUSED) { - // DEBUG ("%s codec decided for call %s",codecName,callID); - // sflphone_display_selected_codec (codecName); } static void @@ -158,9 +156,9 @@ call_state_cb (DBusGProxy *proxy UNUSED, const gchar* callID, const gchar* state } stop_notification(); - sflphone_hung_up (c); calltree_update_call (history, c, NULL); status_bar_display_account(); + sflphone_hung_up (c); } else if (strcmp (state, "UNHOLD_CURRENT") == 0) { sflphone_current (c); } else if (strcmp (state, "UNHOLD_RECORD") == 0) { @@ -222,7 +220,6 @@ conference_changed_cb (DBusGProxy *proxy UNUSED, const gchar* confID, // sflphone_display_transfer_status("Transfer successfull"); conference_obj_t* changed_conf = conferencelist_get (confID); gchar** participants; - gchar** part; DEBUG ("conference new state %s\n", state); @@ -471,13 +468,6 @@ dbus_connect() instanceProxy = dbus_g_proxy_new_for_name (connection, "org.sflphone.SFLphone", "/org/sflphone/SFLphone/Instance", "org.sflphone.SFLphone.Instance"); - /* - instanceProxy = dbus_g_proxy_new_for_name_owner (connection, - "org.sflphone.SFLphone", - "/org/sflphone/SFLphone/Instance", - "org.sflphone.SFLphone.Instance", - &error); - */ if (instanceProxy == NULL) { ERROR ("Failed to get proxy to Instance"); @@ -490,13 +480,6 @@ dbus_connect() "org.sflphone.SFLphone", "/org/sflphone/SFLphone/CallManager", "org.sflphone.SFLphone.CallManager"); - /* - callManagerProxy = dbus_g_proxy_new_for_name_owner (connection, - "org.sflphone.SFLphone", - "/org/sflphone/SFLphone/CallManager", - "org.sflphone.SFLphone.CallManager", - &error); - */ if (callManagerProxy == NULL) { ERROR ("Failed to get proxy to CallManagers"); return FALSE; @@ -639,13 +622,6 @@ dbus_connect() "org.sflphone.SFLphone", "/org/sflphone/SFLphone/ConfigurationManager", "org.sflphone.SFLphone.ConfigurationManager"); - /* - configurationManagerProxy = dbus_g_proxy_new_for_name_owner (connection, - "org.sflphone.SFLphone", - "/org/sflphone/SFLphone/ConfigurationManager", - "org.sflphone.SFLphone.ConfigurationManager", - &error); - */ if (!configurationManagerProxy) { ERROR ("Failed to get proxy to ConfigurationManager"); return FALSE; @@ -873,6 +849,8 @@ dbus_account_details (gchar * accountID) GError *error = NULL; GHashTable * details; + DEBUG ("Dbus: Get account detail accountid %s", accountID); + if (!org_sflphone_SFLphone_ConfigurationManager_get_account_details ( configurationManagerProxy, accountID, &details, &error)) { if (error->domain == DBUS_GERROR && error->code @@ -910,21 +888,6 @@ dbus_set_credential (account_t *a, int index) } } void -dbus_set_number_of_credential (account_t *a, int number) -{ - DEBUG ("Sending number of credential %d to server", number); - GError *error = NULL; - - org_sflphone_SFLphone_ConfigurationManager_set_number_of_credential ( - configurationManagerProxy, a->accountID, number, &error); - - if (error) { - ERROR ("Failed to call set_number_of_credential() on ConfigurationManager: %s", - error->message); - g_error_free (error); - } -} -void dbus_delete_all_credential (account_t *a) { DEBUG ("Deleting all credentials\n"); @@ -1285,27 +1248,14 @@ dbus_get_audio_plugin_list() } void -dbus_set_input_audio_plugin (gchar* audioPlugin) +dbus_set_audio_plugin (gchar* audioPlugin) { GError* error = NULL; - org_sflphone_SFLphone_ConfigurationManager_set_input_audio_plugin ( + org_sflphone_SFLphone_ConfigurationManager_set_audio_plugin ( configurationManagerProxy, audioPlugin, &error); if (error) { - ERROR ("Failed to call set_input_audio_plugin() on ConfigurationManager: %s", error->message); - g_error_free (error); - } -} - -void -dbus_set_output_audio_plugin (gchar* audioPlugin) -{ - GError* error = NULL; - org_sflphone_SFLphone_ConfigurationManager_set_output_audio_plugin ( - configurationManagerProxy, audioPlugin, &error); - - if (error) { - ERROR ("Failed to call set_output_audio_plugin() on ConfigurationManager: %s", error->message); + ERROR ("Failed to call set_audio_plugin() on ConfigurationManager: %s", error->message); g_error_free (error); } } @@ -1524,12 +1474,12 @@ dbus_set_noise_suppress_state (gchar* state) gchar* -dbus_get_ringtone_choice() +dbus_get_ringtone_choice (const gchar *accountID) { gchar* tone; GError* error = NULL; org_sflphone_SFLphone_ConfigurationManager_get_ringtone_choice ( - configurationManagerProxy, &tone, &error); + configurationManagerProxy, accountID, &tone, &error); if (error) { g_error_free (error); @@ -1539,11 +1489,11 @@ dbus_get_ringtone_choice() } void -dbus_set_ringtone_choice (const gchar* tone) +dbus_set_ringtone_choice (const gchar *accountID, const gchar* tone) { GError* error = NULL; org_sflphone_SFLphone_ConfigurationManager_set_ringtone_choice ( - configurationManagerProxy, tone, &error); + configurationManagerProxy, accountID, tone, &error); if (error) { g_error_free (error); @@ -1551,12 +1501,12 @@ dbus_set_ringtone_choice (const gchar* tone) } int -dbus_is_ringtone_enabled() +dbus_is_ringtone_enabled (const gchar *accountID) { int res; GError* error = NULL; org_sflphone_SFLphone_ConfigurationManager_is_ringtone_enabled ( - configurationManagerProxy, &res, &error); + configurationManagerProxy, accountID, &res, &error); if (error) { g_error_free (error); @@ -1566,11 +1516,13 @@ dbus_is_ringtone_enabled() } void -dbus_ringtone_enabled() +dbus_ringtone_enabled (const gchar *accountID) { + DEBUG ("DBUS: Ringtone enabled %s", accountID); + GError* error = NULL; org_sflphone_SFLphone_ConfigurationManager_ringtone_enabled ( - configurationManagerProxy, &error); + configurationManagerProxy, accountID, &error); if (error) { g_error_free (error); @@ -1619,68 +1571,6 @@ dbus_is_iax2_enabled() return res; } -int -dbus_get_dialpad() -{ - int state; - GError* error = NULL; - org_sflphone_SFLphone_ConfigurationManager_get_dialpad ( - configurationManagerProxy, &state, &error); - - if (error) { - g_error_free (error); - } - - return state; -} - -void -dbus_set_dialpad (gboolean display) -{ - - GError* error = NULL; - org_sflphone_SFLphone_ConfigurationManager_set_dialpad ( - configurationManagerProxy, display, &error); - - if (error) { - g_error_free (error); - } -} - -int -dbus_get_searchbar() -{ - int state; - GError* error = NULL; - - if (!org_sflphone_SFLphone_ConfigurationManager_get_searchbar ( - configurationManagerProxy, &state, &error)) { - if (error->domain == DBUS_GERROR && error->code - == DBUS_GERROR_REMOTE_EXCEPTION) { - ERROR ("Caught remote method (get_searchbar) exception %s: %s", dbus_g_error_get_name (error), error->message); - } else { - ERROR ("Error while calling get_searchbar: %s", error->message); - } - - g_error_free (error); - return -1; - } else { - return state; - } -} - -void -dbus_set_searchbar() -{ - GError* error = NULL; - org_sflphone_SFLphone_ConfigurationManager_set_searchbar ( - configurationManagerProxy, &error); - - if (error) { - g_error_free (error); - } -} - void dbus_join_participant (const gchar* sel_callID, const gchar* drag_callID) { @@ -1746,6 +1636,7 @@ dbus_detach_participant (const gchar* callID) } +void dbus_join_conference (const gchar* sel_confID, const gchar* drag_confID) { @@ -1765,7 +1656,7 @@ dbus_join_conference (const gchar* sel_confID, const gchar* drag_confID) void dbus_set_record (const gchar* id) { - DEBUG ("dbus_set_record %s\n", id); + DEBUG ("Dbus: dbus_set_record %s", id); GError* error = NULL; org_sflphone_SFLphone_CallManager_set_recording (callManagerProxy, id, &error); @@ -1778,7 +1669,7 @@ dbus_set_record (const gchar* id) gboolean dbus_get_is_recording (const callable_obj_t * c) { - DEBUG ("dbus_get_is_recording %s\n", c->_callID); + DEBUG ("Dbus: dbus_get_is_recording %s", c->_callID); GError* error = NULL; gboolean isRecording; org_sflphone_SFLphone_CallManager_get_is_recording (callManagerProxy, @@ -2301,146 +2192,6 @@ dbus_get_all_ip_interface_by_name (void) } } -guint -dbus_get_window_width (void) -{ - - GError *error = NULL; - guint value; - - org_sflphone_SFLphone_ConfigurationManager_get_window_width ( - configurationManagerProxy, &value, &error); - - if (error != NULL) { - ERROR ("Failed to call get_window_width() on ConfigurationManager: %s", - error->message); - g_error_free (error); - } - - return value; -} - -guint -dbus_get_window_height (void) -{ - - GError *error = NULL; - guint value; - - org_sflphone_SFLphone_ConfigurationManager_get_window_height ( - configurationManagerProxy, &value, &error); - - if (error != NULL) { - ERROR ("Failed to call get_window_height() on ConfigurationManager: %s", - error->message); - g_error_free (error); - } - - return value; -} - -void -dbus_set_window_width (const guint width) -{ - - GError *error = NULL; - - org_sflphone_SFLphone_ConfigurationManager_set_window_width ( - configurationManagerProxy, width, &error); - - if (error != NULL) { - ERROR ("Failed to call set_window_width() on ConfigurationManager: %s", - error->message); - g_error_free (error); - } -} - -void -dbus_set_window_height (const guint height) -{ - - GError *error = NULL; - - org_sflphone_SFLphone_ConfigurationManager_set_window_height ( - configurationManagerProxy, height, &error); - - if (error != NULL) { - ERROR ("Failed to call set_window_height() on ConfigurationManager: %s", - error->message); - g_error_free (error); - } -} - -guint -dbus_get_window_position_x (void) -{ - - GError *error = NULL; - guint value; - - org_sflphone_SFLphone_ConfigurationManager_get_window_position_x ( - configurationManagerProxy, &value, &error); - - if (error != NULL) { - ERROR ("Failed to call get_window_position_x() on ConfigurationManager: %s", - error->message); - g_error_free (error); - } - - return value; -} - -guint -dbus_get_window_position_y (void) -{ - - GError *error = NULL; - guint value; - - org_sflphone_SFLphone_ConfigurationManager_get_window_position_y ( - configurationManagerProxy, &value, &error); - - if (error != NULL) { - ERROR ("Failed to call get_window_position_y() on ConfigurationManager: %s", - error->message); - g_error_free (error); - } - - return value; -} - -void -dbus_set_window_position_x (const guint posx) -{ - - GError *error = NULL; - - org_sflphone_SFLphone_ConfigurationManager_set_window_position_x ( - configurationManagerProxy, posx, &error); - - if (error != NULL) { - ERROR ("Failed to call set_window_position_x() on ConfigurationManager: %s", - error->message); - g_error_free (error); - } -} - -void -dbus_set_window_position_y (const guint posy) -{ - - GError *error = NULL; - - org_sflphone_SFLphone_ConfigurationManager_set_window_position_y ( - configurationManagerProxy, posy, &error); - - if (error != NULL) { - ERROR ("Failed to call set_window_position_y() on ConfigurationManager: %s", - error->message); - g_error_free (error); - } -} - GHashTable* dbus_get_shortcuts (void) { @@ -2470,6 +2221,7 @@ dbus_set_shortcuts (GHashTable * shortcuts) org_sflphone_SFLphone_ConfigurationManager_set_shortcuts ( configurationManagerProxy, shortcuts, &error); + if (error) { ERROR ("Failed to call set_shortcuts() on ConfigurationManager: %s", error->message); diff --git a/sflphone-client-gnome/src/dbus/dbus.h b/sflphone-client-gnome/src/dbus/dbus.h index f9c6516009751c02f29d6ae364938aa88398dc49..99dce013df8db99d36ef8a262c3c72fded03a5c5 100644 --- a/sflphone-client-gnome/src/dbus/dbus.h +++ b/sflphone-client-gnome/src/dbus/dbus.h @@ -26,7 +26,7 @@ * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. * grants you additional permission to convey the resulting work. * Corresponding Source for a non-source form of such a combination - * shall include the source code for the parts of OpenSSL used as well +* shall include the source code for the parts of OpenSSL used as well * as that of the covered work. */ @@ -145,13 +145,6 @@ int dbus_get_number_of_credential (gchar * accountID); */ void dbus_delete_all_credential (account_t *a); -/** - * ConfigurationManager - Set the number of credential that - * is being used. - * @param a The account id - */ -void dbus_set_number_of_credential (account_t *a, int number); - /** * ConfigurationManager - Set the additional credential information * of a specific account, for a specific credential index. @@ -370,49 +363,25 @@ int dbus_is_iax2_enabled (void); * @return int 1 if enabled * 0 otherwise */ -int dbus_is_ringtone_enabled (void); +int dbus_is_ringtone_enabled (const gchar *accountID); /** * ConfigurationManager - Set the ringtone option * Inverse current value */ -void dbus_ringtone_enabled (void); +void dbus_ringtone_enabled (const gchar *accountID); /** * ConfigurationManager - Get the ringtone * @return gchar* The file name selected as a ringtone */ -gchar* dbus_get_ringtone_choice (void); +gchar* dbus_get_ringtone_choice (const gchar *accountID); /** * ConfigurationManager - Set a ringtone * @param tone The file name of the ringtone */ -void dbus_set_ringtone_choice (const gchar* tone); - -/** - * ConfigurationManager - Set the dialpad visible or not - */ -void dbus_set_dialpad (gboolean display); - -/** - * ConfigurationManager - Tells if the user wants to display the dialpad or not - * @return int 1 if dialpad has to be displayed - * 0 otherwise - */ -int dbus_get_dialpad (void); - -/** - * ConfigurationManager - Set the searchbar visible or not - */ -void dbus_set_searchbar(); - -/** - * ConfigurationManager - Tells if the user wants to display the search bar or not - * @return int 1 if the search bar has to be displayed - * 0 otherwise - */ -int dbus_get_searchbar (void); +void dbus_set_ringtone_choice (const gchar *accountID, const gchar* tone); /** * ConfigurationManager - Gives the maximum number of days the user wants to have in the history @@ -572,18 +541,32 @@ gchar** dbus_get_supported_tls_method(); gchar** dbus_get_participant_list (const char * confID); -guint dbus_get_window_width (void); -guint dbus_get_window_height (void); -void dbus_set_window_height (const guint height); -void dbus_set_window_width (const guint width); -guint dbus_get_window_position_x (void); -guint dbus_get_window_position_y (void); -void dbus_set_window_position_x (const guint posx); -void dbus_set_window_position_y (const guint posy); - GHashTable* dbus_get_shortcuts (void); void dbus_set_shortcuts (GHashTable * shortcuts); +void dbus_set_audio_ringtone_device (const int index); + +void +dbus_hang_up_conference (const conference_obj_t * c); + +void +dbus_hold_conference (const conference_obj_t * c); + +void +dbus_unhold_conference (const conference_obj_t * c); + +void +dbus_detach_participant (const gchar* callID); + +void +dbus_join_participant (const gchar* sel_callID, const gchar* drag_callID); + +void +dbus_join_conference (const gchar* sel_confID, const gchar* drag_confID); + +void +dbus_add_main_participant (const gchar* confID); + /* Instant messaging */ void dbus_send_text_message (const gchar* callID, const gchar *message); diff --git a/sflphone-client-gnome/src/eel-gconf-extensions.c b/sflphone-client-gnome/src/eel-gconf-extensions.c index 1d912000683672b91ca43f58bc7ecbd893dc3e4c..1835935eeddfa86c22201518232f8a3a021dbcdd 100644 --- a/sflphone-client-gnome/src/eel-gconf-extensions.c +++ b/sflphone-client-gnome/src/eel-gconf-extensions.c @@ -590,7 +590,7 @@ gpdf_notification_add (const char *key, if (notifiers != NULL) { *notifiers = g_list_append (*notifiers, - (gpointer) id); + GINT_TO_POINTER (id)); } } diff --git a/sflphone-client-gnome/src/icons/icon_factory.c b/sflphone-client-gnome/src/icons/icon_factory.c index b81365874aa4fc8e6210672c288b2dcdaa4686c5..4b612c1a482d0450f118a74d785199b12c98d8c7 100644 --- a/sflphone-client-gnome/src/icons/icon_factory.c +++ b/sflphone-client-gnome/src/icons/icon_factory.c @@ -29,6 +29,8 @@ */ #include "icon_factory.h" +#include "icons/pixmap_data.h" + static GtkIconFactory *icon_factory = NULL; @@ -58,6 +60,12 @@ void add_icon (GtkIconFactory *factory, const gchar *stock_id, const guint8 *ico DEBUG ("Icon %s already exists in factory\n", stock_id); } +GtkIconSet* lookup_sflphone_factory (const gchar *stock_id) +{ + + return gtk_icon_factory_lookup (icon_factory, stock_id); +} + void register_sflphone_stock_icons (GtkIconFactory *factory) { add_icon (factory, GTK_STOCK_PICKUP, gnome_stock_pickup, GTK_ICON_SIZE_SMALL_TOOLBAR); diff --git a/sflphone-client-gnome/src/icons/icon_factory.h b/sflphone-client-gnome/src/icons/icon_factory.h index e07b1519655b0b7624fef64cfea6e0be89a0ea4d..400006f621bcaf3a5d39e4da893a422f46d71c94 100644 --- a/sflphone-client-gnome/src/icons/icon_factory.h +++ b/sflphone-client-gnome/src/icons/icon_factory.h @@ -53,6 +53,8 @@ G_BEGIN_DECLS void init_icon_factory (void); +GtkIconSet* lookup_sflphone_factory (const gchar *stock_id); + G_END_DECLS #endif diff --git a/sflphone-client-gnome/src/imwindow.c b/sflphone-client-gnome/src/imwindow.c index 44f9be1b2ba3ca2d0f113011340e195945ddf948..4b33e9c278741403413f446bb1fcbfda754c078c 100644 --- a/sflphone-client-gnome/src/imwindow.c +++ b/sflphone-client-gnome/src/imwindow.c @@ -103,7 +103,7 @@ im_window_init() gtk_window_set_default_size (GTK_WINDOW (im_window), width, height); gtk_window_set_default_icon_from_file (LOGO, NULL); gtk_window_set_position (GTK_WINDOW (im_window), GTK_WIN_POS_MOUSE); - // gtk_window_set_resizable (GTK_WINDOW(im_window), FALSE); + gtk_widget_set_name (im_window, "imwindow"); GtkWidget *im_vbox = gtk_vbox_new (FALSE /*homogeneous*/, 0 /*spacing*/); diff --git a/sflphone-client-gnome/src/logger.c b/sflphone-client-gnome/src/logger.c new file mode 100644 index 0000000000000000000000000000000000000000..66994fe0a34c9ab845ea84a5dfc5edc2a0bf38d2 --- /dev/null +++ b/sflphone-client-gnome/src/logger.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Julien Bonjean <julien.bonjean@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#include <logger.h> +#include <stdarg.h> +#include <string.h> +#include <stdio.h> + +int log_level = LOG_INFO; + +void internal_log (const int level, const char* format, ...) +{ + if (level > log_level) + return; + + va_list ap; + char *prefix = "<> "; + char buffer[4000]; + char message[4096]; + + switch (level) { + case LOG_ERR: { + prefix = "<error> "; + break; + } + case LOG_WARN: { + prefix = "<warning> "; + break; + } + case LOG_INFO: { + prefix = "<info> "; + break; + } + case LOG_DEBUG: { + prefix = "<debug> "; + break; + } + } + + va_start (ap, format); + vsprintf (buffer, format, ap); + va_end (ap); + + message[0] = '\0'; + strncat (message, prefix, strlen (prefix)); + strncat (message, buffer, strlen (buffer)); + strncat (message, "\n", 1); + + fprintf (stderr, "%s", message); +} + +void set_log_level (const int level) +{ + log_level = level; +} diff --git a/sflphone-client-gnome/src/logger.h b/sflphone-client-gnome/src/logger.h new file mode 100644 index 0000000000000000000000000000000000000000..0d2ac5c5e435320b242fa33f28e4f27dbdbc20c4 --- /dev/null +++ b/sflphone-client-gnome/src/logger.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Julien Bonjean <julien.bonjean@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#ifndef __LOGGER_H +#define __LOGGER_H + +void internal_log (const int level, const char* format, ...); +void set_log_level (const int level); + +#define LOG_ERR 1 +#define LOG_WARN 2 +#define LOG_INFO 3 +#define LOG_DEBUG 4 + +#define ERROR(...) internal_log(LOG_ERR, __VA_ARGS__) +#define WARN(...) internal_log(LOG_WARN, __VA_ARGS__) +#define INFO(...) internal_log(LOG_INFO, __VA_ARGS__) +#define DEBUG(...) internal_log(LOG_DEBUG, __VA_ARGS__) + +#endif diff --git a/sflphone-client-gnome/src/main.c b/sflphone-client-gnome/src/main.c index b4cdb9a06eafbc52e23654431ac4ab911707b421..b3b6b2ebb150358b78c2e8184bfd0ec63eb3a978 100644 --- a/sflphone-client-gnome/src/main.c +++ b/sflphone-client-gnome/src/main.c @@ -31,58 +31,36 @@ #include <actions.h> #include <calllist.h> #include <config.h> +#include <logger.h> #include <dbus/dbus.h> #include <mainwindow.h> #include <statusicon.h> #include <libgnome/libgnome.h> #include <libgnomeui/libgnomeui.h> +#include <eel-gconf-extensions.h> #include <gtk/gtk.h> #include <stdlib.h> #include "shortcuts.h" -/** - * Stop logging engine - */ -static void -shutdown_logging () -{ - if (log4c_fini ()) { - ERROR ("log4c_fini() failed"); - } -} - -/** - * Start loggin engine - */ -static void -startup_logging () -{ - log4c_init (); - - if (log4c_load (DATA_DIR "/log4crc") == -1) - g_warning ("Cannot load log4j configuration file : %s", DATA_DIR "/log4crc"); - - log4c_sfl_gtk_category = log4c_category_get ("org.sflphone.gtk"); -} - int main (int argc, char *argv[]) { // Handle logging int i; - // Startup logging - startup_logging (); - // Check arguments if debug mode is activated for (i = 0; i < argc; i++) if (g_strcmp0 (argv[i], "--debug") == 0) - log4c_category_set_priority (log4c_sfl_gtk_category, LOG4C_PRIORITY_DEBUG); + set_log_level (LOG_DEBUG); - // Start GTK application + // GtkWidget *window; + g_thread_init (NULL); + gdk_threads_init (); + gdk_threads_enter (); + // Start GTK application gtk_init (&argc, &argv); g_print ("%s %s\n", PACKAGE, VERSION); @@ -100,8 +78,6 @@ main (int argc, char *argv[]) "shall include the source code for the parts of OpenSSL used as well\n" \ "as that of the covered work.\n\n"); - DEBUG ("Logging Started"); - srand (time (NULL)); // Internationalization @@ -144,8 +120,7 @@ main (int argc, char *argv[]) gtk_main (); } - // Cleanly stop logging - shutdown_logging (); + gdk_threads_leave (); shortcuts_destroy_bindings(); diff --git a/sflphone-client-gnome/src/mainwindow.c b/sflphone-client-gnome/src/mainwindow.c index fab4abc95b8be025e16b099b65d1a3a45c4e103b..2494a6875182537e03406a496da0b2a7c04846b1 100644 --- a/sflphone-client-gnome/src/mainwindow.c +++ b/sflphone-client-gnome/src/mainwindow.c @@ -42,6 +42,7 @@ #include <assistant.h> #include <widget/gtkscrollbook.h> #include <widget/minidialog.h> +#include "uimanager.h" #include <gtk/gtk.h> #include <eel-gconf-extensions.h> @@ -59,10 +60,14 @@ GtkWidget * statusBar = NULL; GtkWidget * filterEntry = NULL; PidginScrollBook *embedded_error_notebook; +gchar *status_current_message = NULL; +// pthread_mutex_t statusbar_message_mutex; +GMutex *gmutex; + /** * Handle main window resizing */ -static gboolean window_configure_cb (GtkWidget *win, GdkEventConfigure *event) +static gboolean window_configure_cb (GtkWidget *win UNUSED, GdkEventConfigure *event) { int pos_x, pos_y; @@ -92,6 +97,8 @@ on_delete (GtkWidget * widget UNUSED, gpointer data UNUSED) sflphone_quit (); } + // pthread_mutex_destroy (&statusbar_message_mutex); + g_mutex_free (gmutex); return TRUE; } @@ -136,7 +143,9 @@ on_key_released (GtkWidget *widget, GdkEventKey *event, gpointer user_data UNUSE event->keyval == 34 || // " event->keyval == 65289 || // tab event->keyval == 65361 || // left arrow + event->keyval == 65362 || // up arrow event->keyval == 65363 || // right arrow + event->keyval == 65364 || // down arrow event->keyval >= 65470 || // F-keys event->keyval == 32 // space ) @@ -165,7 +174,6 @@ void create_main_window () { GtkWidget *widget; - gchar *path; GError *error = NULL; gboolean ret; const char *window_title = "SFLphone VoIP Client"; @@ -288,6 +296,9 @@ create_main_window () /* don't show waiting layer */ gtk_widget_hide (waitingLayer); + // pthread_mutex_init (&statusbar_message_mutex, NULL); + gmutex = g_mutex_new(); + // Configuration wizard if (account_list_get_size () == 1) { #if GTK_CHECK_VERSION(2,10,0) @@ -394,9 +405,32 @@ main_window_volume_controls (gboolean state) } void -statusbar_push_message (const gchar * message, guint id) +statusbar_push_message (const gchar *left_hand_message, const gchar *right_hand_message, guint id) { - gtk_statusbar_push (GTK_STATUSBAR (statusBar), id, message); + // The actual message to be push in the statusbar + gchar *message_to_display; + + g_mutex_lock (gmutex); + // pthread_mutex_lock (&statusbar_message_mutex); + + g_free (status_current_message); + // store the left hand message so that it can be reused in case of clock update + status_current_message = g_strdup (left_hand_message); + + // Format message according to right hand member + if (right_hand_message) + message_to_display = g_strdup_printf ("%s %s", + left_hand_message, right_hand_message); + else + message_to_display = g_strdup (left_hand_message); + + // Push into the statusbar + gtk_statusbar_push (GTK_STATUSBAR (statusBar), id, message_to_display); + + g_free (message_to_display); + + // pthread_mutex_unlock (&statusbar_message_mutex); + g_mutex_unlock (gmutex); } void @@ -405,6 +439,33 @@ statusbar_pop_message (guint id) gtk_statusbar_pop (GTK_STATUSBAR (statusBar), id); } +void +statusbar_update_clock (gchar *msg) +{ + gchar *message = NULL; + + if (!msg) { + statusbar_pop_message (__MSG_ACCOUNT_DEFAULT); + statusbar_push_message (message, NULL, __MSG_ACCOUNT_DEFAULT); + } + + + // pthread_mutex_lock (&statusbar_message_mutex); + g_mutex_lock (gmutex); + message = g_strdup (status_current_message); + // pthread_mutex_unlock (&statusbar_message_mutex); + g_mutex_unlock (gmutex); + + if (message) { + statusbar_pop_message (__MSG_ACCOUNT_DEFAULT); + statusbar_push_message (message, msg, __MSG_ACCOUNT_DEFAULT); + } + + g_free (message); + message = NULL; + +} + static void add_error_dialog (GtkWidget *dialog, callable_obj_t * call) { diff --git a/sflphone-client-gnome/src/mainwindow.h b/sflphone-client-gnome/src/mainwindow.h index c54b9d95ea6dc7296091103821b99b5dfde7ac27..991bbcb6cc826563159e464537ff93d31bda1714 100644 --- a/sflphone-client-gnome/src/mainwindow.h +++ b/sflphone-client-gnome/src/mainwindow.h @@ -94,10 +94,11 @@ void main_window_info_message (gchar * markup); /** * Push a message on the statusbar stack - * @param message The message to display + * @param left_hand_message The message to display on the left side + * @param right_hand_message The message to display on the right side * @param id The identifier of the message */ -void statusbar_push_message (const gchar* message , guint id); +void statusbar_push_message (const gchar *left_hand_message, const gchar *right_hand_message, guint id); /** * Pop a message from the statusbar stack @@ -105,6 +106,13 @@ void statusbar_push_message (const gchar* message , guint id); */ void statusbar_pop_message (guint id); +/** + * Update selected call's clock in statusbar + * @param id The identifier of the message + */ +void statusbar_update_clock (gchar *time); + + //static gboolean //on_key_released (GtkWidget *widget, GdkEventKey *event, // gpointer user_data); diff --git a/sflphone-client-gnome/src/sflnotify.c b/sflphone-client-gnome/src/sflnotify.c index fbbc5baa2405132ee1560dfc4df4a49f8cac970f..76de2d319460f15a9e9f950d32e51467373ec805 100644 --- a/sflphone-client-gnome/src/sflnotify.c +++ b/sflphone-client-gnome/src/sflnotify.c @@ -28,7 +28,8 @@ * as that of the covered work. */ -#include <sflnotify.h> +#include "sflnotify.h" +#include <eel-gconf-extensions.h> GnomeNotification *_gnome_notification; diff --git a/sflphone-client-gnome/src/sflphone_const.h b/sflphone-client-gnome/src/sflphone_const.h index bf613935076a3b5d5bad1f54116d9f4b6d0a6ee0..034a40bb44bbdccc3f750f41a4b67b9f984558a3 100644 --- a/sflphone-client-gnome/src/sflphone_const.h +++ b/sflphone-client-gnome/src/sflphone_const.h @@ -32,8 +32,9 @@ #define __SFLPHONE_CONST_H #include <libintl.h> +#include "logger.h" #include "dbus.h" -#include "log4c.h" +#include <glib/gi18n.h> /* @file sflphone_const.h * @brief Contains the global variables for the client code @@ -49,8 +50,8 @@ #define CONTACTS "contacts" /** Locale */ -#define _(STRING) gettext( STRING ) -#define N_(STRING) (STRING) +//#define _(STRING) gettext( STRING ) +//#define N_(STRING) (STRING) #define c_(COMMENT,STRING) gettext(STRING) #define n_(SING,PLUR,COUNT) ngettext(SING,PLUR,COUNT) @@ -87,9 +88,12 @@ #define ACCOUNT_ZRTP_NOT_SUPP_WARNING "ZRTP.notSuppWarning" #define ACCOUNT_ZRTP_HELLO_HASH "ZRTP.helloHashEnable" #define ACCOUNT_DISPLAY_SAS_ONCE "ZRTP.displaySasOnce" -#define KEY_EXCHANGE_NONE "0" -#define ZRTP "1" -#define SDES "2" +#define KEY_EXCHANGE_NONE "none" +#define ZRTP "zrtp" +#define SDES "sdes" + +#define CONFIG_RINGTONE_PATH "Account.ringtonePath" +#define CONFIG_RINGTONE_ENABLED "Account.ringtoneEnabled" #define TLS_LISTENER_PORT "TLS.listenerPort" #define TLS_ENABLE "TLS.enable" @@ -117,10 +121,11 @@ #define REGISTRATION_STATE_CODE "Registration.code" #define REGISTRATION_STATE_DESCRIPTION "Registration.description" -/** - * Global logger - */ -log4c_category_t* log4c_sfl_gtk_category; +#define SHORTCUT_PICKUP "pickUp" +#define SHORTCUT_HANGUP "hangUp" +#define SHORTCUT_POPUP "popupWindow" +#define SHORTCUT_TOGGLEPICKUPHANGUP "togglePickupHangup" +#define SHORTCUT_TOGGLEHOLD "toggleHold" /** Error while opening capture device */ #define ALSA_CAPTURE_DEVICE 0x0001 @@ -169,14 +174,6 @@ log4c_category_t* log4c_sfl_gtk_category; /** Desktop notifications - Time before to close the notification*/ #define __TIMEOUT_TIME 18000 // 30 secondes -/** - * Macros for logging - */ -#define DEBUG(...) log4c_category_log(log4c_sfl_gtk_category, LOG4C_PRIORITY_DEBUG, __VA_ARGS__); -#define WARN(...) log4c_category_log(log4c_sfl_gtk_category, LOG4C_PRIORITY_WARN, __VA_ARGS__); -#define ERROR(...) log4c_category_log(log4c_sfl_gtk_category, LOG4C_PRIORITY_ERROR, __VA_ARGS__); -#define FATAL(...) log4c_category_log(log4c_sfl_gtk_category, LOG4C_PRIORITY_FATAL, __VA_ARGS__); - /** * Gconf */ diff --git a/sflphone-client-gnome/src/shortcuts.c b/sflphone-client-gnome/src/shortcuts.c index 11e3889463a0356bad6556359b21ad37e9e2354e..217254687d89b2e8ff9052f0f756fedc2cfe2bda 100644 --- a/sflphone-client-gnome/src/shortcuts.c +++ b/sflphone-client-gnome/src/shortcuts.c @@ -29,19 +29,28 @@ */ #include <string.h> -#include <stdlib.h> #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> #include <X11/Xlib.h> #include <X11/XF86keysym.h> #include <gdk/gdkx.h> #include <dbus/dbus-glib.h> +#include <stdlib.h> +#include <stdio.h> #include "shortcuts.h" #include "mainwindow.h" #include "callable_obj.h" #include "sflphone_const.h" #include "dbus.h" +#include "actions.h" + +static void +ungrab_key (guint key, GdkModifierType mask, const GdkWindow *root); + +static void +grab_key (guint key, GdkModifierType mask, const GdkWindow *root); + // used to store accelerator config static Accelerator* accelerators_list; @@ -49,10 +58,55 @@ static Accelerator* accelerators_list; // used to store config (for dbus calls) static GHashTable* shortcutsMap; + /* - * Callbacks + * XLib functions + */ + +/* + * filter used when an event is catched */ +static GdkFilterReturn +filter_keys (const GdkXEvent *xevent, const GdkEvent *event UNUSED, gpointer data UNUSED) +{ + XEvent *xev = NULL; + XKeyEvent *key = NULL; + GdkModifierType keystate = 0; + int i = 0; + + xev = (XEvent *) xevent; + + if (xev->type != KeyPress) { + return GDK_FILTER_CONTINUE; + } + + key = (XKeyEvent *) xevent; + keystate = key->state & ~ (Mod2Mask | Mod5Mask | LockMask); + + // try to find corresponding action + while (accelerators_list[i].action != NULL) { + if (accelerators_list[i].key == key->keycode && accelerators_list[i].mask + == keystate) { + DEBUG ("catched key for action: %s", accelerators_list[i].action, + accelerators_list[i].key); + + // call associated callback function + accelerators_list[i].callback (); + + return GDK_FILTER_REMOVE; + } + + i++; + } + + DEBUG ("Should not be reached"); + return GDK_FILTER_CONTINUE; +} + +/* + * Callbacks + */ static void toggle_pick_up_hang_up_callback () { @@ -74,6 +128,8 @@ toggle_pick_up_hang_up_callback () case CALL_STATE_RINGING: sflphone_hang_up (); break; + default: + break; } } else if (selectedConf) { dbus_hang_up_conference (selectedConf); @@ -104,11 +160,13 @@ toggle_hold_callback () case CALL_STATE_CURRENT: case CALL_STATE_RECORD: g_print ("on hold\n"); - sflphone_on_hold(); + sflphone_on_hold (); break; case CALL_STATE_HOLD: g_print ("off hold\n"); - sflphone_off_hold(); + sflphone_off_hold (); + break; + default: break; } } else if (selectedConf) @@ -122,8 +180,8 @@ popup_window_callback () { gtk_widget_hide (GTK_WIDGET (get_main_window())); gtk_widget_show (GTK_WIDGET (get_main_window())); - gtk_window_move (GTK_WINDOW (get_main_window ()), - dbus_get_window_position_x (), dbus_get_window_position_y ()); + //gtk_window_move (GTK_WINDOW (get_main_window ()), + // dbus_get_window_position_x (), dbus_get_window_position_y ()); } static void @@ -138,19 +196,19 @@ default_callback () static void* get_action_callback (const gchar* action) { - if (strcmp (action, "pick_up") == 0) + if (strcmp (action, SHORTCUT_PICKUP) == 0) return pick_up_callback; - if (strcmp (action, "hang_up") == 0) + if (strcmp (action, SHORTCUT_HANGUP) == 0) return hang_up_callback; - if (strcmp (action, "popup_window") == 0) + if (strcmp (action, SHORTCUT_POPUP) == 0) return popup_window_callback; - if (strcmp (action, "toggle_pick_up_hang_up") == 0) + if (strcmp (action, SHORTCUT_TOGGLEPICKUPHANGUP) == 0) return toggle_pick_up_hang_up_callback; - if (strcmp (action, "toggle_hold") == 0) + if (strcmp (action, SHORTCUT_TOGGLEHOLD) == 0) return toggle_hold_callback; return default_callback; @@ -166,29 +224,33 @@ get_action_callback (const gchar* action) static void remove_bindings () { - GdkDisplay *display; - GdkScreen *screen; - GdkWindow *root; + GdkDisplay *display = NULL; + GdkScreen *screen = NULL; + GdkWindow *root = NULL; + int i, j = 0; display = gdk_display_get_default (); - int i = 0; - int j = 0; + for (i = 0; i < gdk_display_get_n_screens (display); i++) { + screen = gdk_display_get_screen (display, i); - while (accelerators_list[i].action != NULL) { - if (accelerators_list[i].value != 0) { - for (j = 0; j < gdk_display_get_n_screens (display); j++) { - screen = gdk_display_get_screen (display, j); - - if (screen != NULL) { - root = gdk_screen_get_root_window (screen); - ungrab_key (accelerators_list[i].value, root); - gdk_window_remove_filter (root, filter_keys, NULL); + if (screen != NULL) { + j = 0; + root = gdk_screen_get_root_window (screen); + + // remove filter + gdk_window_remove_filter (root, (GdkFilterFunc) filter_keys, NULL); + + // unbind shortcuts + while (accelerators_list[j].action != NULL) { + if (accelerators_list[j].key != 0) { + ungrab_key (accelerators_list[j].key, + accelerators_list[j].mask, root); } + + j++; } } - - i++; } } @@ -201,27 +263,30 @@ create_bindings () GdkDisplay *display; GdkScreen *screen; GdkWindow *root; + int i, j = 0; display = gdk_display_get_default (); - int i = 0; - int j = 0; + for (i = 0; i < gdk_display_get_n_screens (display); i++) { + screen = gdk_display_get_screen (display, i); - while (accelerators_list[i].action != NULL) { - if (accelerators_list[i].value != 0) { - // updated GDK bindings - for (j = 0; j < gdk_display_get_n_screens (display); j++) { - screen = gdk_display_get_screen (display, j); - - if (screen != NULL) { - root = gdk_screen_get_root_window (screen); - grab_key (accelerators_list[i].value, root); - gdk_window_add_filter (root, filter_keys, NULL); + if (screen != NULL) { + j = 0; + root = gdk_screen_get_root_window (screen); + + // add filter + gdk_window_add_filter (root, (GdkFilterFunc) filter_keys, NULL); + + // bind shortcuts + while (accelerators_list[j].action != NULL) { + if (accelerators_list[j].key != 0) { + grab_key (accelerators_list[j].key, + accelerators_list[j].mask, root); } + + j++; } } - - i++; } } @@ -229,26 +294,26 @@ create_bindings () * Initialize a specific binding */ static void -initialize_binding (const gchar* action, const guint code) +initialize_binding (const gchar* action, guint key, GdkModifierType mask) { - //initialize_shortcuts_keys(); - int index = 0; + int i = 0; - while (accelerators_list[index].action != NULL) { - if (strcmp (action, accelerators_list[index].action) == 0) { + while (accelerators_list[i].action != NULL) { + if (strcmp (action, accelerators_list[i].action) == 0) { break; } - index++; + i++; } - if (accelerators_list[index].action == NULL) { + if (accelerators_list[i].action == NULL) { ERROR ("Should not happen: cannot find corresponding action"); return; } // update config value - accelerators_list[index].value = code; + accelerators_list[i].key = key; + accelerators_list[i].mask = mask; // update bindings create_bindings (); @@ -260,60 +325,74 @@ initialize_binding (const gchar* action, const guint code) static void initialize_accelerators_list () { - GList* shortcutsKeys = g_hash_table_get_keys (shortcutsMap); + GList* shortcutsKeysElement, *shortcutsKeys = NULL; + int i = 0; + + shortcutsKeys = g_hash_table_get_keys (shortcutsMap); accelerators_list = (Accelerator*) malloc ( (g_list_length (shortcutsKeys) + 1) * sizeof (Accelerator)); - GList* shortcutsKeysElement; - int index = 0; - for (shortcutsKeysElement = shortcutsKeys; shortcutsKeysElement; shortcutsKeysElement = shortcutsKeysElement->next) { gchar* action = shortcutsKeysElement->data; - accelerators_list[index].action = g_strdup (action); - accelerators_list[index].callback = get_action_callback (action); - accelerators_list[index].mask = 0; - accelerators_list[index].value = 0; + accelerators_list[i].action = g_strdup (action); + accelerators_list[i].callback = get_action_callback (action); + accelerators_list[i].mask = 0; + accelerators_list[i].key = 0; - index++; + i++; } // last element must be null - accelerators_list[index].action = 0; - accelerators_list[index].callback = 0; - accelerators_list[index].mask = 0; - accelerators_list[index].value = 0; + accelerators_list[i].action = 0; + accelerators_list[i].callback = 0; + accelerators_list[i].mask = 0; + accelerators_list[i].key = 0; } static void -update_bindings_data (const guint index, const guint code) +update_shortcuts_map (const gchar* action, guint key, GdkModifierType mask) +{ + gchar buffer[7]; + + // Bindings: MASKxCODE + sprintf (buffer, "%dx%d", mask, key); + + g_hash_table_replace (shortcutsMap, g_strdup (action), g_strdup (buffer)); +} + +static void +update_bindings_data (guint index, guint key, GdkModifierType mask) { - // we need to be sure this code is not already affected - // to another action int i = 0; + // we need to be sure this code is not already affected + // to another action while (accelerators_list[i].action != NULL) { - if (accelerators_list[i].value == code) { + if (accelerators_list[i].key == key && accelerators_list[i].mask == mask + && accelerators_list[i].key != 0) { + DEBUG ("Existing mapping found %d+%d", mask, key); + // disable old binding - accelerators_list[i].value = 0; + accelerators_list[i].key = 0; + accelerators_list[i].mask = 0; // update config table - g_hash_table_replace (shortcutsMap, g_strdup ( - accelerators_list[i].action), GINT_TO_POINTER (0)); + update_shortcuts_map (accelerators_list[i].action, 0, 0); } i++; } - // store new value - accelerators_list[index].value = code; + // store new key + accelerators_list[index].key = key; + accelerators_list[index].mask = mask; // update value in hashtable (used for dbus calls) - g_hash_table_replace (shortcutsMap, - g_strdup (accelerators_list[index].action), GINT_TO_POINTER ( - accelerators_list[index].value)); + update_shortcuts_map (accelerators_list[index].action, + accelerators_list[index].key, accelerators_list[index].mask); } /* @@ -324,13 +403,13 @@ update_bindings_data (const guint index, const guint code) * Update current bindings with a new value */ void -shortcuts_update_bindings (const guint index, const guint code) +shortcuts_update_bindings (guint index, guint key, GdkModifierType mask) { // first remove all existing bindings remove_bindings (); // update data - update_bindings_data (index, code); + update_bindings_data (index, key, mask); // recreate all bindings create_bindings (); @@ -345,6 +424,12 @@ shortcuts_update_bindings (const guint index, const guint code) void shortcuts_initialize_bindings () { + GList* shortcutsKeys, *shortcutsKeysElement = NULL; + gchar* action, *maskAndKey, *token1, *token2 = NULL; + guint mask, key = 0; + + DEBUG ("Shortcuts: Initialize bindings"); + // get shortcuts stored in config through dbus shortcutsMap = dbus_get_shortcuts (); @@ -352,16 +437,29 @@ shortcuts_initialize_bindings () initialize_accelerators_list (); // iterate through keys to initialize bindings - GList* shortcutsKeys = g_hash_table_get_keys (shortcutsMap); - GList* shortcutsKeysElement; + shortcutsKeys = g_hash_table_get_keys (shortcutsMap); for (shortcutsKeysElement = shortcutsKeys; shortcutsKeysElement; shortcutsKeysElement = shortcutsKeysElement->next) { - gchar* key = shortcutsKeysElement->data; - int shortcut = (size_t) g_hash_table_lookup (shortcutsMap, key); + action = shortcutsKeysElement->data; + maskAndKey = g_strdup (g_hash_table_lookup (shortcutsMap, action)); - if (shortcut != 0) - initialize_binding (key, shortcut); + token1 = strtok (maskAndKey, "x"); + token2 = strtok (NULL, "x"); + + mask = 0; + key = 0; + + // Value not setted + if (token1 && token2) { + DEBUG ("Ahortcuts: token1 %s, token2 %s", token1, token2); + + mask = atoi (token1); + key = atoi (token2); + } + + if (key != 0) + initialize_binding (action, key, mask); } } @@ -371,15 +469,15 @@ shortcuts_initialize_bindings () void shortcuts_destroy_bindings () { + int i = 0; + // remove bindings remove_bindings (); // free pointers - int index = 0; - - while (accelerators_list[index].action != NULL) { - g_free (accelerators_list[index].action); - index++; + while (accelerators_list[i].action != NULL) { + g_free (accelerators_list[i].action); + i++; } free (accelerators_list); @@ -391,73 +489,33 @@ shortcuts_get_list () return accelerators_list; } -/* - * XLib functions - */ - -/* - * filter used when an event is catched - */ -static GdkFilterReturn -filter_keys (GdkXEvent *xevent, GdkEvent *event, gpointer data) -{ - XEvent *xev; - XKeyEvent *key; - - xev = (XEvent *) xevent; - - if (xev->type != KeyPress) { - return GDK_FILTER_CONTINUE; - } - - key = (XKeyEvent *) xevent; - - // try to find corresponding action - int i = 0; - - while (accelerators_list[i].action != NULL) { - if (accelerators_list[i].value == key->keycode) { - DEBUG ("catched key for action: %s (%d)", accelerators_list[i].action, - accelerators_list[i].value); - - // call associated callback function - accelerators_list[i].callback (); - - return GDK_FILTER_REMOVE; - } - - i++; - } - - DEBUG ("Should not be reached :(\n"); - return GDK_FILTER_CONTINUE; -} - /* * Remove key "catcher" from GDK layer */ static void -ungrab_key (int key_code, GdkWindow *root) +ungrab_key (guint key, GdkModifierType mask, const GdkWindow *root) { + DEBUG ("Ungrabbing key %d+%d", mask, key); + gdk_error_trap_push (); - XUngrabKey (GDK_DISPLAY(), key_code, 0, GDK_WINDOW_XID (root)); - XUngrabKey (GDK_DISPLAY(), key_code, Mod2Mask, GDK_WINDOW_XID (root)); - XUngrabKey (GDK_DISPLAY(), key_code, Mod5Mask, GDK_WINDOW_XID (root)); - XUngrabKey (GDK_DISPLAY(), key_code, LockMask, GDK_WINDOW_XID (root)); - XUngrabKey (GDK_DISPLAY(), key_code, Mod2Mask | Mod5Mask, - GDK_WINDOW_XID (root)); - XUngrabKey (GDK_DISPLAY(), key_code, Mod2Mask | LockMask, - GDK_WINDOW_XID (root)); - XUngrabKey (GDK_DISPLAY(), key_code, Mod5Mask | LockMask, - GDK_WINDOW_XID (root)); - XUngrabKey (GDK_DISPLAY(), key_code, Mod2Mask | Mod5Mask | LockMask, - GDK_WINDOW_XID (root)); + XUngrabKey (GDK_DISPLAY (), key, mask, GDK_WINDOW_XID ( (GdkDrawable*) root)); + XUngrabKey (GDK_DISPLAY (), key, Mod2Mask | mask, GDK_WINDOW_XID ( (GdkDrawable*) root)); + XUngrabKey (GDK_DISPLAY (), key, Mod5Mask | mask, GDK_WINDOW_XID ( (GdkDrawable*) root)); + XUngrabKey (GDK_DISPLAY (), key, LockMask | mask, GDK_WINDOW_XID ( (GdkDrawable*) root)); + XUngrabKey (GDK_DISPLAY (), key, Mod2Mask | Mod5Mask | mask, + GDK_WINDOW_XID ( (GdkDrawable*) root)); + XUngrabKey (GDK_DISPLAY (), key, Mod2Mask | LockMask | mask, + GDK_WINDOW_XID ( (GdkDrawable*) root)); + XUngrabKey (GDK_DISPLAY (), key, Mod5Mask | LockMask | mask, + GDK_WINDOW_XID ( (GdkDrawable*) root)); + XUngrabKey (GDK_DISPLAY (), key, Mod2Mask | Mod5Mask | LockMask | mask, + GDK_WINDOW_XID ( (GdkDrawable*) root)); gdk_flush (); if (gdk_error_trap_pop ()) { - ERROR ("Error ungrabbing key"); + DEBUG ("Error ungrabbing key %d+%d", mask, key); } } @@ -465,31 +523,32 @@ ungrab_key (int key_code, GdkWindow *root) * Add key "catcher" to GDK layer */ static void -grab_key (int key_code, GdkWindow *root) +grab_key (guint key, GdkModifierType mask, const GdkWindow *root) { - gdk_error_trap_push (); - XGrabKey (GDK_DISPLAY(), key_code, 0, GDK_WINDOW_XID (root), True, + DEBUG ("Grabbing key %d+%d", mask, key); + + XGrabKey (GDK_DISPLAY(), key, mask, GDK_WINDOW_XID ( (GdkDrawable*) root), True, GrabModeAsync, GrabModeAsync); - XGrabKey (GDK_DISPLAY(), key_code, Mod2Mask, GDK_WINDOW_XID (root), True, + XGrabKey (GDK_DISPLAY (), key, Mod2Mask | mask, GDK_WINDOW_XID ( (GdkDrawable*) root), True, GrabModeAsync, GrabModeAsync); - XGrabKey (GDK_DISPLAY(), key_code, Mod5Mask, GDK_WINDOW_XID (root), True, + XGrabKey (GDK_DISPLAY (), key, Mod5Mask | mask, GDK_WINDOW_XID ( (GdkDrawable*) root), True, GrabModeAsync, GrabModeAsync); - XGrabKey (GDK_DISPLAY(), key_code, LockMask, GDK_WINDOW_XID (root), True, + XGrabKey (GDK_DISPLAY (), key, LockMask | mask, GDK_WINDOW_XID ( (GdkDrawable*) root), True, GrabModeAsync, GrabModeAsync); - XGrabKey (GDK_DISPLAY(), key_code, Mod2Mask | Mod5Mask, GDK_WINDOW_XID (root), - True, GrabModeAsync, GrabModeAsync); - XGrabKey (GDK_DISPLAY(), key_code, Mod2Mask | LockMask, GDK_WINDOW_XID (root), - True, GrabModeAsync, GrabModeAsync); - XGrabKey (GDK_DISPLAY(), key_code, Mod5Mask | LockMask, GDK_WINDOW_XID (root), - True, GrabModeAsync, GrabModeAsync); - XGrabKey (GDK_DISPLAY(), key_code, Mod2Mask | Mod5Mask | LockMask, - GDK_WINDOW_XID (root), True, GrabModeAsync, GrabModeAsync); + XGrabKey (GDK_DISPLAY (), key, Mod2Mask | Mod5Mask | mask, + GDK_WINDOW_XID ( (GdkDrawable*) root), True, GrabModeAsync, GrabModeAsync); + XGrabKey (GDK_DISPLAY (), key, Mod2Mask | LockMask | mask, + GDK_WINDOW_XID ( (GdkDrawable*) root), True, GrabModeAsync, GrabModeAsync); + XGrabKey (GDK_DISPLAY (), key, Mod5Mask | LockMask | mask, + GDK_WINDOW_XID ( (GdkDrawable*) root), True, GrabModeAsync, GrabModeAsync); + XGrabKey (GDK_DISPLAY (), key, Mod2Mask | Mod5Mask | LockMask | mask, + GDK_WINDOW_XID ( (GdkDrawable*) root), True, GrabModeAsync, GrabModeAsync); gdk_flush (); if (gdk_error_trap_pop ()) { - ERROR ("Error grabbing key"); + DEBUG ("Error grabbing key %d+%d", mask, key); } } diff --git a/sflphone-client-gnome/src/shortcuts.h b/sflphone-client-gnome/src/shortcuts.h index fda7f8940a23749bdbe94ef4b393556a4e2cef85..20703ce8ada5cb94e6d15c3afd709528cf9119f7 100644 --- a/sflphone-client-gnome/src/shortcuts.h +++ b/sflphone-client-gnome/src/shortcuts.h @@ -33,60 +33,17 @@ typedef struct { gchar *action; + guint key; GdkModifierType mask; - guint value; void (*callback) (void); } Accelerator; -static void -grab_key (int key_code, GdkWindow *root); - -static void -ungrab_key (int key_code, GdkWindow *root); - -static GdkFilterReturn -filter_keys (GdkXEvent *xevent, GdkEvent *event, gpointer data); - -static void -remove_bindings (); - -static void -create_bindings (); - -static void -pick_up_callback (); - -static void -hang_up_callback (); - -static void -toggle_pick_up_hang_up_callback (); - -static void -toggle_hold_callback (); - -static void -initialize_binding (const gchar* action, const guint code); - -static void -initialize_shortcuts_keys (); - -static void* -get_action_callback (const gchar* action); - -static void -update_bindings_data (const guint index, const guint code); - -/* - * "Public" functions - */ - void shortcuts_initialize_bindings (); void -shortcuts_update_bindings (const guint index, const guint code); +shortcuts_update_bindings (guint index, guint key, GdkModifierType mask); void shortcuts_destroy_bindings (); diff --git a/sflphone-client-gnome/src/statusicon.c b/sflphone-client-gnome/src/statusicon.c index 93348e1e5d068c101da36cef8280f5d6f2b09942..134dfbeeca42a38f59cb0f52e6476bc9708003d4 100644 --- a/sflphone-client-gnome/src/statusicon.c +++ b/sflphone-client-gnome/src/statusicon.c @@ -34,6 +34,7 @@ #include <mainwindow.h> #include <accountlist.h> #include <statusicon.h> +#include <eel-gconf-extensions.h> #if GTK_CHECK_VERSION(2,10,0) GtkStatusIcon *status; @@ -45,8 +46,8 @@ popup_main_window (void) { if (__POPUP_WINDOW) { gtk_widget_show (get_main_window()); - gtk_window_move (GTK_WINDOW (get_main_window ()), - dbus_get_window_position_x(), dbus_get_window_position_y()); + //gtk_window_move(GTK_WINDOW (get_main_window ()), + // dbus_get_window_position_x(), dbus_get_window_position_y()); set_minimized (FALSE); } } diff --git a/sflphone-client-gnome/src/statusicon.h b/sflphone-client-gnome/src/statusicon.h index 1245ced88e335f9ed4414056a417e7c7cf5268c4..951276cfeaef4f739f7ccbfce2637cb24018e9b2 100644 --- a/sflphone-client-gnome/src/statusicon.h +++ b/sflphone-client-gnome/src/statusicon.h @@ -107,6 +107,8 @@ GtkStatusIcon* get_status_icon (void); */ void statusicon_set_tooltip (void); +void status_tray_icon_online (gboolean online); + #endif // GTK_CHECK_VERSION #endif diff --git a/sflphone-client-gnome/src/toolbar.c b/sflphone-client-gnome/src/toolbar.c index af5966c063ca1d6bcb8a148e30494405c24e2548..95713da293b7ea4c4a6f85556f40cd4fdae37a62 100644 --- a/sflphone-client-gnome/src/toolbar.c +++ b/sflphone-client-gnome/src/toolbar.c @@ -48,7 +48,7 @@ call_mailbox (GtkWidget* widget UNUSED, gpointer data UNUSED) account_id = g_strdup (current->accountID); create_new_call (CALL, CALL_STATE_DIALING, "", account_id, _ ("Voicemail"), to, &mailbox_call); - DEBUG ("TO : %s" , mailbox_call->_peer_number); + DEBUG ("Call: TO : %s" , mailbox_call->_peer_number); calllist_add (current_calls , mailbox_call); calltree_add_call (current_calls, mailbox_call, NULL); update_actions(); @@ -62,7 +62,6 @@ call_mailbox (GtkWidget* widget UNUSED, gpointer data UNUSED) static void call_button (GtkWidget *widget UNUSED, gpointer data UNUSED) { - DEBUG ("------ call_button -----"); callable_obj_t * selectedCall; callable_obj_t* new_call; diff --git a/sflphone-client-gnome/src/uimanager.c b/sflphone-client-gnome/src/uimanager.c index 35c9628bc831440c4e660d2b84c5dedd285cbeef..95fedd24dd9951690de5027bd980cdf8e401f51e 100644 --- a/sflphone-client-gnome/src/uimanager.c +++ b/sflphone-client-gnome/src/uimanager.c @@ -37,9 +37,18 @@ #include <string.h> #include <glib/gprintf.h> #include <libgnome/gnome-help.h> + #include <uimanager.h> #include <statusicon.h> #include <widget/imwidget.h> +#include <eel-gconf-extensions.h> +#include "uimanager.h" +#include "statusicon.h" +#include "contacts/addressbook.h" +#include "accountlist.h" +#include "config/accountlistconfigdialog.h" + +void show_edit_number (callable_obj_t *call); static GtkWidget *toolbar; static GtkWidget *toolbarWindows; @@ -83,7 +92,7 @@ void update_actions() { - DEBUG ("Update action"); + DEBUG ("UIManager: Update action"); gtk_action_set_sensitive (GTK_ACTION (newCallAction), TRUE); gtk_action_set_sensitive (GTK_ACTION (pickUpAction), FALSE); @@ -175,6 +184,10 @@ update_actions() } } + // g_signal_handler_block (GTK_OBJECT (recordWidget), recordButtonConnId); + // gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (recordWidget), FALSE); + // g_signal_handler_unblock (GTK_OBJECT (recordWidget), recordButtonConnId); + callable_obj_t * selectedCall = calltab_get_selected_call (active_calltree); conference_obj_t * selectedConf = calltab_get_selected_conf (active_calltree); @@ -222,21 +235,17 @@ update_actions() //gtk_action_set_sensitive( GTK_ACTION(newCallMenu),TRUE); g_object_ref (newCallWidget); - gtk_container_remove (GTK_CONTAINER (toolbar), - GTK_WIDGET (newCallWidget)); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (pickUpWidget), - 0); + gtk_container_remove (GTK_CONTAINER (toolbar), GTK_WIDGET (newCallWidget)); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (pickUpWidget), 0); if (active_calltree == current_calls) - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), - GTK_TOOL_ITEM (hangUpWidget), 1); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), 1); break; case CALL_STATE_CURRENT: - case CALL_STATE_RECORD: + DEBUG ("UIManager: Call State Current"); gtk_action_set_sensitive (GTK_ACTION (hangUpAction), TRUE); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), - 1); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), 1); gtk_widget_set_sensitive (GTK_WIDGET (holdMenu), TRUE); gtk_widget_set_sensitive (GTK_WIDGET (holdToolbar), TRUE); gtk_widget_set_sensitive (GTK_WIDGET (transferToolbar), TRUE); @@ -251,25 +260,41 @@ update_actions() gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (imToolbar), 5); gtk_signal_handler_block (GTK_OBJECT (transferToolbar), transfertButtonConnId); - gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (transferToolbar), FALSE); + gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (transferToolbar), FALSE); gtk_signal_handler_unblock (transferToolbar, transfertButtonConnId); + g_signal_handler_block (GTK_OBJECT (recordWidget), recordButtonConnId); + gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (recordWidget), FALSE); + g_signal_handler_unblock (GTK_OBJECT (recordWidget), recordButtonConnId); + break; + case CALL_STATE_RECORD: + DEBUG ("UIManager: Call State Record"); + gtk_action_set_sensitive (GTK_ACTION (hangUpAction), TRUE); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), 1); + gtk_widget_set_sensitive (GTK_WIDGET (holdMenu), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (holdToolbar), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (transferToolbar), TRUE); + gtk_action_set_sensitive (GTK_ACTION (recordAction), TRUE); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (holdToolbar), 2); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (transferToolbar), 3); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (recordWidget), 4); + gtk_signal_handler_block (GTK_OBJECT (transferToolbar), transfertButtonConnId); + gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (transferToolbar), FALSE); + gtk_signal_handler_unblock (transferToolbar, transfertButtonConnId); + g_signal_handler_block (GTK_OBJECT (recordWidget), recordButtonConnId); + gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (recordWidget), TRUE); + g_signal_handler_unblock (GTK_OBJECT (recordWidget), recordButtonConnId); break; case CALL_STATE_BUSY: case CALL_STATE_FAILURE: gtk_action_set_sensitive (GTK_ACTION (hangUpAction), TRUE); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), - 1); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), 1); break; case CALL_STATE_TRANSFERT: - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), - 1); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), - GTK_TOOL_ITEM (transferToolbar), 2); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), 1); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (transferToolbar), 2); gtk_signal_handler_block (GTK_OBJECT (transferToolbar), transfertButtonConnId); - gtk_toggle_tool_button_set_active ( - GTK_TOGGLE_TOOL_BUTTON (transferToolbar), TRUE); + gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (transferToolbar), TRUE); gtk_signal_handler_unblock (transferToolbar, transfertButtonConnId); gtk_action_set_sensitive (GTK_ACTION (hangUpAction), TRUE); gtk_widget_set_sensitive (GTK_WIDGET (holdMenu), TRUE); @@ -277,8 +302,7 @@ update_actions() gtk_widget_set_sensitive (GTK_WIDGET (transferToolbar), TRUE); break; default: - WARN ("Should not happen in update_actions()!") - ; + WARN ("Should not happen in update_actions()!"); break; } } else if (selectedConf) { @@ -291,42 +315,42 @@ update_actions() case CONFERENCE_STATE_ACTIVE_ATACHED: gtk_action_set_sensitive (GTK_ACTION (hangUpAction), TRUE); gtk_widget_set_sensitive (GTK_WIDGET (holdToolbar), TRUE); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), - 1); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (holdToolbar), - 2); + gtk_action_set_sensitive (GTK_ACTION (recordAction), TRUE); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), 1); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (holdToolbar), 2); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (recordWidget), 3); break; case CONFERENCE_STATE_ACTIVE_DETACHED: gtk_action_set_sensitive (GTK_ACTION (hangUpAction), TRUE); gtk_widget_set_sensitive (GTK_WIDGET (holdToolbar), TRUE); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), - 1); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (holdToolbar), - 2); + gtk_action_set_sensitive (GTK_ACTION (recordAction), TRUE); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), 1); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (holdToolbar), 2); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (recordWidget), 3); break; case CONFERENCE_STATE_RECORD: + DEBUG ("UIManager: Conference state record"); gtk_action_set_sensitive (GTK_ACTION (hangUpAction), TRUE); gtk_widget_set_sensitive (GTK_WIDGET (holdToolbar), TRUE); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), - 1); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (holdToolbar), - 2); + gtk_action_set_sensitive (GTK_ACTION (recordAction), TRUE); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), 1); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (holdToolbar), 2); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (recordWidget), 3); break; case CONFERENCE_STATE_HOLD: gtk_action_set_sensitive (GTK_ACTION (hangUpAction), TRUE); gtk_widget_set_sensitive (GTK_WIDGET (offHoldToolbar), TRUE); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), - 1); - gtk_toolbar_insert (GTK_TOOLBAR (toolbar), - GTK_TOOL_ITEM (offHoldToolbar), 2); + gtk_action_set_sensitive (GTK_ACTION (recordAction), TRUE); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (hangUpWidget), 1); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (offHoldToolbar), 2); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (recordWidget), 3); break; default: - WARN ("Should not happen in update_action()!") - ; + WARN ("Should not happen in update_action()!"); break; } @@ -360,7 +384,7 @@ update_voicemail_status (void) } static void -volume_bar_cb (GtkToggleAction *togglemenuitem, gpointer user_data) +volume_bar_cb (GtkToggleAction *togglemenuitem, gpointer user_data UNUSED) { gboolean toggled = gtk_toggle_action_get_active (togglemenuitem); @@ -374,7 +398,7 @@ volume_bar_cb (GtkToggleAction *togglemenuitem, gpointer user_data) } static void -dialpad_bar_cb (GtkToggleAction *togglemenuitem, gpointer user_data) +dialpad_bar_cb (GtkToggleAction *togglemenuitem, gpointer user_data UNUSED) { gboolean toggled = gtk_toggle_action_get_active (togglemenuitem); gboolean conf_dialpad = eel_gconf_get_boolean (CONF_SHOW_DIALPAD); @@ -390,7 +414,7 @@ dialpad_bar_cb (GtkToggleAction *togglemenuitem, gpointer user_data) } static void -help_contents_cb (GtkAction *action) +help_contents_cb (GtkAction *action UNUSED) { GError *error = NULL; @@ -438,6 +462,8 @@ help_about (void * foo UNUSED) static void call_new_call (void * foo UNUSED) { + DEBUG ("UIManager: New call button pressed"); + sflphone_new_call(); } @@ -474,6 +500,8 @@ call_hold (void* foo UNUSED) callable_obj_t * selectedCall = calltab_get_selected_call (current_calls); conference_obj_t * selectedConf = calltab_get_selected_conf(); + DEBUG ("UIManager: Hold button pressed (call)"); + if (selectedCall) { if (selectedCall->_state == CALL_STATE_HOLD) { sflphone_off_hold(); @@ -520,6 +548,8 @@ conference_hold (void* foo UNUSED) { conference_obj_t * selectedConf = calltab_get_selected_conf(); + DEBUG ("UIManager: Hold button pressed (conference)"); + switch (selectedConf->_state) { case CONFERENCE_STATE_HOLD: { selectedConf->_state = CONFERENCE_STATE_ACTIVE_ATACHED; @@ -572,6 +602,8 @@ call_pick_up (void * foo UNUSED) static void call_hang_up (void) { + + DEBUG ("UIManager: Hang up button pressed (call)"); /* * [#3020] Restore the record toggle button * We set it to FALSE, as when we hang up a call, the recording is stopped. @@ -585,12 +617,16 @@ call_hang_up (void) static void conference_hang_up (void) { + DEBUG ("UIManager: Hang up button pressed (conference)"); + sflphone_conference_hang_up(); } static void call_record (void) { + DEBUG ("UIManager: Record button pressed"); + sflphone_rec_call(); } @@ -608,7 +644,7 @@ remove_from_history (void * foo UNUSED) callable_obj_t* c = calltab_get_selected_call (history); if (c) { - DEBUG ("Remove the call from the history"); + DEBUG ("UIManager: Remove the call from the history"); calllist_remove_from_history (c); } } @@ -668,7 +704,7 @@ edit_copy (void * foo UNUSED) break; } - DEBUG ("Clipboard number: %s\n", no); + DEBUG ("UIManager: Clipboard number: %s\n", no); gtk_clipboard_set_text (clip, no, strlen (no)); } @@ -709,7 +745,6 @@ edit_paste (void * foo UNUSED) case CALL_STATE_HOLD: { // Create a new call to hold the new text selectedCall = sflphone_new_call(); - gchar * before = selectedCall->_peer_number; selectedCall->_peer_number = g_strconcat (selectedCall->_peer_number, no, NULL); DEBUG ("TO: %s", selectedCall->_peer_number); @@ -748,7 +783,7 @@ edit_paste (void * foo UNUSED) selectedCall->_peer_number = g_strconcat (selectedCall->_peer_number, no, NULL); g_free (before); - DEBUG ("TO: %s", selectedCall->_peer_number); + DEBUG ("UIManager: TO: %s", selectedCall->_peer_number); g_free (selectedCall->_peer_info); selectedCall->_peer_info = g_strconcat ("\"\" <", @@ -782,7 +817,7 @@ call_mailbox_cb (void) { account_t* current; callable_obj_t *mailbox_call; - gchar *to, *from, *account_id; + gchar *to, *account_id; current = account_list_get_current(); @@ -803,7 +838,7 @@ call_mailbox_cb (void) } static void -toggle_history_cb (GtkToggleAction *action, gpointer user_data) +toggle_history_cb (GtkToggleAction *action, gpointer user_data UNUSED) { gboolean toggle; toggle = gtk_toggle_action_get_active (action); @@ -811,7 +846,7 @@ toggle_history_cb (GtkToggleAction *action, gpointer user_data) } static void -toggle_addressbook_cb (GtkToggleAction *action, gpointer user_data) +toggle_addressbook_cb (GtkToggleAction *action, gpointer user_data UNUSED) { gboolean toggle; toggle = gtk_toggle_action_get_active (action); @@ -871,21 +906,13 @@ static const GtkActionEntry menu_entries[] = { static const GtkToggleActionEntry toggle_menu_entries[] = { - { "Transfer", GTK_STOCK_TRANSFER, N_ ("_Transfer"), "<control>T", - N_ ("Transfer the call"), NULL }, //G_CALLBACK (call_transfer_cb) }, - { "Record", GTK_STOCK_MEDIA_RECORD, N_ ("_Record"), "<control>R", - N_ ("Record the current conversation"), NULL }, // G_CALLBACK (call_record) }, - { "Toolbar", NULL, N_ ("_Show toolbar"), "<control>T", - N_ ("Show the toolbar"), NULL }, - { "Dialpad", NULL, N_ ("_Dialpad"), "<control>D", - N_ ("Show the dialpad"), G_CALLBACK (dialpad_bar_cb) }, - { "VolumeControls", NULL, N_ ("_Volume controls"), "<control>V", - N_ ("Show the volume controls"), G_CALLBACK (volume_bar_cb) }, - { "History", "appointment-soon", N_ ("_History"), NULL, - N_ ("Calls history"), G_CALLBACK (toggle_history_cb), FALSE }, - { "Addressbook", GTK_STOCK_ADDRESSBOOK, N_ ("_Address book"), NULL, - N_ ("Address book"), G_CALLBACK (toggle_addressbook_cb), FALSE } - + { "Transfer", GTK_STOCK_TRANSFER, N_ ("_Transfer"), "<control>T", N_ ("Transfer the call"), NULL, TRUE }, + { "Record", GTK_STOCK_MEDIA_RECORD, N_ ("_Record"), "<control>R", N_ ("Record the current conversation"), NULL, TRUE }, + { "Toolbar", NULL, N_ ("_Show toolbar"), "<control>T", N_ ("Show the toolbar"), NULL, TRUE }, + { "Dialpad", NULL, N_ ("_Dialpad"), "<control>D", N_ ("Show the dialpad"), G_CALLBACK (dialpad_bar_cb), TRUE }, + { "VolumeControls", NULL, N_ ("_Volume controls"), "<control>V", N_ ("Show the volume controls"), G_CALLBACK (volume_bar_cb), TRUE }, + { "History", "appointment-soon", N_ ("_History"), NULL, N_ ("Calls history"), G_CALLBACK (toggle_history_cb), FALSE }, + { "Addressbook", GTK_STOCK_ADDRESSBOOK, N_ ("_Address book"), NULL, N_ ("Address book"), G_CALLBACK (toggle_addressbook_cb), FALSE } }; gboolean @@ -1002,18 +1029,17 @@ show_popup_menu (GtkWidget *my_widget, GdkEventButton *event) // call type boolean gboolean pickup = FALSE, hangup = FALSE, hold = FALSE, copy = FALSE, record = - FALSE, detach = FALSE; + FALSE, detach = FALSE, im = FALSE; gboolean accounts = FALSE; - gboolean im = FALSE; // conference type boolean gboolean hangup_conf = FALSE, hold_conf = FALSE; - callable_obj_t * selectedCall; + callable_obj_t * selectedCall = NULL; conference_obj_t * selectedConf; if (calltab_get_selected_type (current_calls) == A_CALL) { - DEBUG ("MENUS: SELECTED A CALL"); + DEBUG ("UIManager: Menus: Selected a call"); selectedCall = calltab_get_selected_call (current_calls); if (selectedCall) { @@ -1052,13 +1078,13 @@ show_popup_menu (GtkWidget *my_widget, GdkEventButton *event) hangup = TRUE; break; default: - WARN ("Should not happen in show_popup_menu for calls!") + WARN ("UIManager: Should not happen in show_popup_menu for calls!") ; break; } } } else { - DEBUG ("MENUS: SELECTED A CONF"); + DEBUG ("UIManager: Menus: selected a conf"); selectedConf = calltab_get_selected_conf(); if (selectedConf) { @@ -1074,7 +1100,7 @@ show_popup_menu (GtkWidget *my_widget, GdkEventButton *event) hold_conf = TRUE; break; default: - WARN ("Should not happen in show_popup_menu for conferences!") + WARN ("UIManager: Should not happen in show_popup_menu for conferences!") ; break; } @@ -1092,7 +1118,7 @@ show_popup_menu (GtkWidget *my_widget, GdkEventButton *event) //g_signal_connect (menu, "deactivate", // G_CALLBACK (gtk_widget_destroy), NULL); if (calltab_get_selected_type (current_calls) == A_CALL) { - DEBUG ("BUILD CALL MENU"); + DEBUG ("UIManager: Build call menu"); if (copy) { menu_items = gtk_image_menu_item_new_from_stock (GTK_STOCK_COPY, @@ -1180,7 +1206,7 @@ show_popup_menu (GtkWidget *my_widget, GdkEventButton *event) } } else { - DEBUG ("BUILD CONFERENCE MENU"); + DEBUG ("UIManager: Build call menus"); if (hangup_conf) { menu_items = gtk_image_menu_item_new_with_mnemonic (_ ("_Hang up")); @@ -1225,6 +1251,8 @@ void show_popup_menu_history (GtkWidget *my_widget, GdkEventButton *event) { + DEBUG ("UIManager: Show popup menu history"); + gboolean pickup = FALSE; gboolean remove = FALSE; gboolean edit = FALSE; @@ -1293,6 +1321,75 @@ show_popup_menu_history (GtkWidget *my_widget, GdkEventButton *event) gtk_menu_attach_to_widget (GTK_MENU (menu), my_widget, NULL); gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, button, event_time); } + +/* +void +show_popup_menu_addressbook (GtkWidget *my_widget, GdkEventButton *event) +{ + + if (selectedCall) { + remove = TRUE; + pickup = TRUE; + edit = TRUE; + accounts = TRUE; + } + + GtkWidget *menu; + GtkWidget *image; + int button, event_time; + GtkWidget * menu_items; + + menu = gtk_menu_new(); + //g_signal_connect (menu, "deactivate", + // G_CALLBACK (gtk_widget_destroy), NULL); + + if (pickup) { + + menu_items = gtk_image_menu_item_new_with_mnemonic (_ ("_Call back")); + image = gtk_image_new_from_file (ICONS_DIR "/icon_accept.svg"); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_items), image); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items); + g_signal_connect (G_OBJECT (menu_items), "activate",G_CALLBACK (call_back), NULL); + gtk_widget_show (menu_items); + } + + menu_items = gtk_separator_menu_item_new(); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items); + gtk_widget_show (menu_items); + + if (edit) { + menu_items = gtk_image_menu_item_new_from_stock (GTK_STOCK_EDIT, + get_accel_group()); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items); + g_signal_connect (G_OBJECT (menu_items), "activate",G_CALLBACK (edit_number_cb), selectedCall); + gtk_widget_show (menu_items); + } + + if (remove) { + menu_items = gtk_image_menu_item_new_from_stock (GTK_STOCK_DELETE, + get_accel_group()); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items); + g_signal_connect (G_OBJECT (menu_items), "activate", G_CALLBACK (remove_from_history), NULL); + gtk_widget_show (menu_items); + } + + if (accounts) { + add_registered_accounts_to_menu (menu); + } + + if (event) { + button = event->button; + event_time = event->time; + } else { + button = 0; + event_time = gtk_get_current_event_time(); + } + + gtk_menu_attach_to_widget (GTK_MENU (menu), my_widget, NULL); + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, button, event_time); +} +*/ + void show_popup_menu_contacts (GtkWidget *my_widget, GdkEventButton *event) { diff --git a/sflphone-client-gnome/src/uimanager.h b/sflphone-client-gnome/src/uimanager.h index 23bebef995e10ce8406c2fa82853faf2dbc62b8d..33bd0279393641c2cb4122c15e75fdcfc77b45f8 100644 --- a/sflphone-client-gnome/src/uimanager.h +++ b/sflphone-client-gnome/src/uimanager.h @@ -44,10 +44,20 @@ GtkAction *volumeToggle; gboolean uimanager_new (GtkUIManager**); -static void show_edit_number (); - void update_voicemail_status (void); +void update_actions (void); + +void show_popup_menu (GtkWidget *my_widget, GdkEventButton *event); + +void show_popup_menu_history (GtkWidget *my_widget, GdkEventButton *event); + +void show_popup_menu_contacts (GtkWidget *my_widget, GdkEventButton *event); + +void create_menus (GtkUIManager *ui_manager, GtkWidget **widget); + +void create_toolbar_actions (GtkUIManager *ui_manager, GtkWidget **widget); + G_END_DECLS #endif diff --git a/sflphone-client-gnome/src/widget/gtkscrollbook.c b/sflphone-client-gnome/src/widget/gtkscrollbook.c index 18023bb6e1350d1e1379cb560a97f044696a5ddf..0b481a5ef179b9577d67d83863dbaa5d9ee1e414 100644 --- a/sflphone-client-gnome/src/widget/gtkscrollbook.c +++ b/sflphone-client-gnome/src/widget/gtkscrollbook.c @@ -25,7 +25,7 @@ */ #include "gtkscrollbook.h" - +#include "sflphone_const.h" static void pidgin_scroll_book_init (PidginScrollBook *scroll_book); static void pidgin_scroll_book_class_init (PidginScrollBookClass *klass); @@ -148,7 +148,7 @@ scroll_close_cb (PidginScrollBook *scroll_book) } static void -switch_page_cb (GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, PidginScrollBook *scroll_book) +switch_page_cb (GtkNotebook *notebook UNUSED, GtkNotebookPage *page UNUSED, guint page_num, PidginScrollBook *scroll_book) { int count; #if GTK_CHECK_VERSION(2,2,0) @@ -236,7 +236,7 @@ pidgin_scroll_book_class_init (PidginScrollBookClass *klass) } static gboolean -close_button_left_cb (GtkWidget *widget, GdkEventCrossing *event, GtkLabel *label) +close_button_left_cb (GtkWidget *widget UNUSED, GdkEventCrossing *event, GtkLabel *label) { static GdkCursor *ptr = NULL; @@ -250,7 +250,7 @@ close_button_left_cb (GtkWidget *widget, GdkEventCrossing *event, GtkLabel *labe } static gboolean -close_button_entered_cb (GtkWidget *widget, GdkEventCrossing *event, GtkLabel *label) +close_button_entered_cb (GtkWidget *widget UNUSED, GdkEventCrossing *event, GtkLabel *label) { static GdkCursor *hand = NULL; diff --git a/sflphone-client-gnome/src/widget/minidialog.c b/sflphone-client-gnome/src/widget/minidialog.c index ad003a5a9a00abef22f03d2b1ba2807cc6d5d2b7..3867d19e7373031ab9e1f76bbd466e9fb1654eca 100644 --- a/sflphone-client-gnome/src/widget/minidialog.c +++ b/sflphone-client-gnome/src/widget/minidialog.c @@ -26,7 +26,7 @@ #include <gtk/gtkhbox.h> #include <gtk/gtkbutton.h> #include <gtk/gtk.h> - +#include "sflphone_const.h" #include "minidialog.h" #define HIG_BOX_SPACE 6 @@ -165,7 +165,7 @@ mini_dialog_button_clicked_cb (GtkButton *button, } static void -mini_dialog_button_destroy_cb (GtkButton *button, +mini_dialog_button_destroy_cb (GtkButton *button UNUSED, gpointer user_data) { struct _mini_dialog_button_clicked_cb_data *data = user_data; @@ -356,20 +356,6 @@ pidgin_mini_dialog_class_init (PidginMiniDialogClass *klass) #define BLIST_WIDTH_PREF \ (PIDGIN_PREFS_ROOT "/blist/width") -static void -blist_width_changed_cb (const char *name, - gconstpointer val, - gpointer data) -{ - PidginMiniDialog *self = PIDGIN_MINI_DIALOG (data); - PidginMiniDialogPrivate *priv = PIDGIN_MINI_DIALOG_GET_PRIVATE (self); - guint blist_width = GPOINTER_TO_INT (val); - guint label_width = LABEL_WIDTH; - - gtk_widget_set_size_request (GTK_WIDGET (priv->title), label_width, -1); - gtk_widget_set_size_request (GTK_WIDGET (priv->desc), label_width, -1); -} - static void pidgin_mini_dialog_init (PidginMiniDialog *self) { diff --git a/sflphone-client-gnome/tests/Makefile.am b/sflphone-client-gnome/tests/Makefile.am index ba1161ae750bf07180fc71504a88bcf0e97dda49..3d3ffb8f4dfa7d8216f47ae495b5f310a1c76e29 100644 --- a/sflphone-client-gnome/tests/Makefile.am +++ b/sflphone-client-gnome/tests/Makefile.am @@ -27,24 +27,24 @@ SFLPHONE_OBJ = $(top_builddir)/src/accountlist.o \ check_global_SOURCES = check_global.c check_global_CFLAGS = @CHECK_CFLAGS@ @DEPS_CFLAGS@ -check_global_LDADD = $(SFLPHONE_LIBS) $(SFLPHONE_OBJ) @CHECK_LIBS@ $(DEPS_LIBS) @LIBSEXY_LIBS@ -llog4c +check_global_LDADD = $(SFLPHONE_LIBS) $(SFLPHONE_OBJ) @CHECK_LIBS@ $(DEPS_LIBS) @LIBSEXY_LIBS@ ########################################################### check_contacts_SOURCES = check_contacts.c check_contacts_CFLAGS = @CHECK_CFLAGS@ @DEPS_CFLAGS@ -check_contacts_LDADD = $(SFLPHONE_LIBS) $(SFLPHONE_OBJ) @CHECK_LIBS@ $(DEPS_LIBS) @LIBSEXY_LIBS@ -llog4c +check_contacts_LDADD = $(SFLPHONE_LIBS) $(SFLPHONE_OBJ) @CHECK_LIBS@ $(DEPS_LIBS) @LIBSEXY_LIBS@ ########################################################### check_config_SOURCES = check_config.c check_config_CFLAGS = @CHECK_CFLAGS@ @DEPS_CFLAGS@ -check_config_LDADD = $(SFLPHONE_LIBS) $(SFLPHONE_OBJ) @CHECK_LIBS@ @DEPS_LIBS@ @LIBSEXY_LIBS@ -llog4c +check_config_LDADD = $(SFLPHONE_LIBS) $(SFLPHONE_OBJ) @CHECK_LIBS@ @DEPS_LIBS@ @LIBSEXY_LIBS@ ########################################################### check_dbus_SOURCES = check_dbus.c check_dbus_CFLAGS = @CHECK_CFLAGS@ @DEPS_CFLAGS@ -check_dbus_LDADD = $(SFLPHONE_LIBS) $(SFLPHONE_OBJ) @CHECK_LIBS@ @DEPS_LIBS@ @LIBSEXY_LIBS@ -llog4c +check_dbus_LDADD = $(SFLPHONE_LIBS) $(SFLPHONE_OBJ) @CHECK_LIBS@ @DEPS_LIBS@ @LIBSEXY_LIBS@ ########################################################### diff --git a/sflphone-common/Makefile.am b/sflphone-common/Makefile.am index c5de2501fbb765d640061938f15ce4b259270a3a..22a5bfd63002c0aad55e909ccf821d0dd87b2988 100644 --- a/sflphone-common/Makefile.am +++ b/sflphone-common/Makefile.am @@ -24,13 +24,6 @@ doc: @echo "D-Bus API HTML documentation has been generated in doc/dbus-api/doc/spec" @echo "" -indent: - @echo "Indenting code:" - if [ -f $(ASTYLERC) ] ; then \ - $(indent) --options=$(ASTYLERC) --recursive *.cpp *.h; \ - fi - - ACLOCAL_AMFLAGS = -I m4 SUBDIRS = libs src ringtones man $(TESTS_DIR) EXTRA_DIST = m4/*.m4 tools/*.sh platform/* images/* README.gentoo diff --git a/sflphone-common/ccccreports/cccc.xml b/sflphone-common/ccccreports/cccc.xml new file mode 100644 index 0000000000000000000000000000000000000000..96ea4f390c72b4ede2d580215e806bc859adf537 --- /dev/null +++ b/sflphone-common/ccccreports/cccc.xml @@ -0,0 +1,1215 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Report on software metrics--> +<CCCC_Project> +<timestamp>Tue Aug 31 09:59:48 2010 +</timestamp> +<project_summary> +<number_of_modules value="39" level="0" /> +<lines_of_code value="3910" level="0" /> +<lines_of_code_per_module value="100.256" level="0" /> +<McCabes_cyclomatic_complexity value="756" level="0" /> +<McCabes_cyclomatic_complexity_per_module value="19.385" level="0" /> +<lines_of_comment value="837" level="0" /> +<lines_of_comment_per_module value="21.462" level="0" /> +<lines_of_code_per_line_of_comment value="4.671" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="0.903" level="0" /> +<IF4 value="113" level="0" /> +<IF4_per_module value="2.897" level="0" /> +<IF4_visible value="113" level="0" /> +<IF4_visible_per_module value="2.897" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4_concrete value="0.000" level="0" /> +<rejected_lines_of_code value="48" level="0" /> +</project_summary> +<procedural_summary> +<module> +<name>Account</name> +<lines_of_code value="56" level="0" /> +<McCabes_cyclomatic_complexity value="4" level="0" /> +<lines_of_comment value="42" level="0" /> +<lines_of_code_per_line_of_comment value="1.333" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>AccountCreator</name> +<lines_of_code value="29" level="0" /> +<McCabes_cyclomatic_complexity value="8" level="0" /> +<lines_of_comment value="29" level="0" /> +<lines_of_code_per_line_of_comment value="1.000" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="0.276" level="0" /> +</module> +<module> +<name>AccountID</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>AccountType</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>AddressbookPreference</name> +<lines_of_code value="74" level="0" /> +<McCabes_cyclomatic_complexity value="24" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="******" level="2" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="******" level="2" /> +</module> +<module> +<name>AlsaLayer</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>AudioPreference</name> +<lines_of_code value="154" level="0" /> +<McCabes_cyclomatic_complexity value="20" level="0" /> +<lines_of_comment value="25" level="0" /> +<lines_of_code_per_line_of_comment value="6.160" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="0.800" level="0" /> +</module> +<module> +<name>AudioThread</name> +<lines_of_code value="12" level="0" /> +<McCabes_cyclomatic_complexity value="1" level="0" /> +<lines_of_comment value="4" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>Call</name> +<lines_of_code value="132" level="0" /> +<McCabes_cyclomatic_complexity value="25" level="0" /> +<lines_of_comment value="31" level="0" /> +<lines_of_code_per_line_of_comment value="4.258" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="0.806" level="0" /> +</module> +<module> +<name>CallConfiguration</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>CallID</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>CallState</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>CallType</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>ConfID</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>Conference</name> +<lines_of_code value="98" level="0" /> +<McCabes_cyclomatic_complexity value="15" level="0" /> +<lines_of_comment value="4" level="0" /> +<lines_of_code_per_line_of_comment value="24.500" level="1" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="3.750" level="0" /> +</module> +<module> +<name>ConferenceState</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>ConnectionState</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>EventThread</name> +<lines_of_code value="11" level="0" /> +<McCabes_cyclomatic_complexity value="1" level="0" /> +<lines_of_comment value="32" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>HookPreference</name> +<lines_of_code value="64" level="0" /> +<McCabes_cyclomatic_complexity value="14" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="******" level="2" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="******" level="2" /> +</module> +<module> +<name>ManagerImpl</name> +<lines_of_code value="2687" level="2" /> +<McCabes_cyclomatic_complexity value="544" level="1" /> +<lines_of_comment value="360" level="0" /> +<lines_of_code_per_line_of_comment value="7.464" level="1" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="1.511" level="0" /> +</module> +<module> +<name>MappingNode</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>NumberCleaner</name> +<lines_of_code value="21" level="0" /> +<McCabes_cyclomatic_complexity value="2" level="0" /> +<lines_of_comment value="29" level="0" /> +<lines_of_code_per_line_of_comment value="0.724" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>Observer</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>Preferences</name> +<lines_of_code value="114" level="0" /> +<McCabes_cyclomatic_complexity value="23" level="0" /> +<lines_of_comment value="29" level="0" /> +<lines_of_code_per_line_of_comment value="3.931" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="0.793" level="0" /> +</module> +<module> +<name>RegistrationState</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>ShortcutPreferences</name> +<lines_of_code value="90" level="0" /> +<McCabes_cyclomatic_complexity value="13" level="0" /> +<lines_of_comment value="10" level="0" /> +<lines_of_code_per_line_of_comment value="9.000" level="1" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="1.300" level="0" /> +</module> +<module> +<name>Subject</name> +<lines_of_code value="23" level="0" /> +<McCabes_cyclomatic_complexity value="4" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="******" level="2" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>TONEID</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>TokenList</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>VoIPLink</name> +<lines_of_code value="52" level="0" /> +<McCabes_cyclomatic_complexity value="12" level="0" /> +<lines_of_comment value="32" level="0" /> +<lines_of_code_per_line_of_comment value="1.625" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="0.375" level="0" /> +</module> +<module> +<name>VoipPreference</name> +<lines_of_code value="68" level="0" /> +<McCabes_cyclomatic_complexity value="17" level="0" /> +<lines_of_comment value="2" level="0" /> +<lines_of_code_per_line_of_comment value="34.000" level="2" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="8.500" level="1" /> +</module> +<module> +<name>YamlEmitter</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>anonymous</name> +<lines_of_code value="177" level="0" /> +<McCabes_cyclomatic_complexity value="29" level="0" /> +<lines_of_comment value="46" level="0" /> +<lines_of_code_per_line_of_comment value="3.848" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="0.630" level="0" /> +</module> +<module> +<name>bool</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>int32_t</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>map</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>short</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>string</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +<module> +<name>vector</name> +<lines_of_code value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<lines_of_code_per_line_of_comment value="------" level="0" /> +<McCabes_cyclomatic_complexity_per_line_of_comment value="------" level="0" /> +</module> +</procedural_summary> +<oo_design> +<module> +<name>Account</name> +<weighted_methods_per_class_unity value="6" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="4" level="0" /> +</module> +<module> +<name>AccountCreator</name> +<weighted_methods_per_class_unity value="3" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="2" level="0" /> +</module> +<module> +<name>AccountID</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="4" level="0" /> +</module> +<module> +<name>AccountType</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>AddressbookPreference</name> +<weighted_methods_per_class_unity value="4" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="2" level="0" /> +</module> +<module> +<name>AlsaLayer</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>AudioPreference</name> +<weighted_methods_per_class_unity value="4" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="2" level="0" /> +</module> +<module> +<name>AudioThread</name> +<weighted_methods_per_class_unity value="2" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>Call</name> +<weighted_methods_per_class_unity value="12" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="7" level="0" /> +</module> +<module> +<name>CallConfiguration</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>CallID</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="4" level="0" /> +</module> +<module> +<name>CallState</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>CallType</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>ConfID</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>Conference</name> +<weighted_methods_per_class_unity value="10" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="3" level="0" /> +</module> +<module> +<name>ConferenceState</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>ConnectionState</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>EventThread</name> +<weighted_methods_per_class_unity value="2" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>HookPreference</name> +<weighted_methods_per_class_unity value="4" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="2" level="0" /> +</module> +<module> +<name>ManagerImpl</name> +<weighted_methods_per_class_unity value="159" level="2" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="14" level="1" /> +</module> +<module> +<name>MappingNode</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="6" level="0" /> +</module> +<module> +<name>NumberCleaner</name> +<weighted_methods_per_class_unity value="4" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>Observer</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>Preferences</name> +<weighted_methods_per_class_unity value="4" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="2" level="0" /> +</module> +<module> +<name>RegistrationState</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>ShortcutPreferences</name> +<weighted_methods_per_class_unity value="6" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="3" level="0" /> +</module> +<module> +<name>Subject</name> +<weighted_methods_per_class_unity value="3" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>TONEID</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>TokenList</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>VoIPLink</name> +<weighted_methods_per_class_unity value="7" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="4" level="0" /> +</module> +<module> +<name>VoipPreference</name> +<weighted_methods_per_class_unity value="4" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="2" level="0" /> +</module> +<module> +<name>YamlEmitter</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="6" level="0" /> +</module> +<module> +<name>anonymous</name> +<weighted_methods_per_class_unity value="10" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="0" level="0" /> +</module> +<module> +<name>bool</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="2" level="0" /> +</module> +<module> +<name>int32_t</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>map</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="2" level="0" /> +</module> +<module> +<name>short</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="1" level="0" /> +</module> +<module> +<name>string</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="3" level="0" /> +</module> +<module> +<name>vector</name> +<weighted_methods_per_class_unity value="0" level="0" /> +<weighted_methods_per_class_visibility value="0" level="0" /> +<depth_of_inheritance_tree value="0" level="0" /> +<number_of_children value="0" level="0" /> +<coupling_between_objects value="2" level="0" /> +</module> +</oo_design> +<structural_summary> +<module> +<name>Account</name> +<fan_out_visible value="0" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="0" level="0" /> +<fan_in_visible value="4" level="0" /> +<fan_in_concrete value="2" level="0" /> +<fan_in value="4" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>AccountCreator</name> +<fan_out_visible value="0" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="0" level="0" /> +<fan_in_visible value="2" level="0" /> +<fan_in_concrete value="2" level="0" /> +<fan_in value="2" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>AccountID</name> +<fan_out_visible value="4" level="0" /> +<fan_out_concrete value="1" level="0" /> +<fan_out value="4" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>AccountType</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="1" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>AddressbookPreference</name> +<fan_out_visible value="0" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="0" level="0" /> +<fan_in_visible value="2" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="2" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>AlsaLayer</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>AudioPreference</name> +<fan_out_visible value="0" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="0" level="0" /> +<fan_in_visible value="2" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="2" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>AudioThread</name> +<fan_out_visible value="0" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="0" level="0" /> +<fan_in_visible value="1" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="1" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>Call</name> +<fan_out_visible value="2" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="2" level="0" /> +<fan_in_visible value="5" level="0" /> +<fan_in_concrete value="4" level="0" /> +<fan_in value="5" level="0" /> +<IF4_visible value="100" level="1" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="100" level="0" /> +</module> +<module> +<name>CallConfiguration</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="1" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>CallID</name> +<fan_out_visible value="4" level="0" /> +<fan_out_concrete value="2" level="0" /> +<fan_out value="4" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>CallState</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="1" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>CallType</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="1" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>ConfID</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>Conference</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="2" level="0" /> +<fan_in_concrete value="2" level="0" /> +<fan_in value="2" level="0" /> +<IF4_visible value="4" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="4" level="0" /> +</module> +<module> +<name>ConferenceState</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="1" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>ConnectionState</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="1" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>EventThread</name> +<fan_out_visible value="0" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="0" level="0" /> +<fan_in_visible value="1" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="1" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>HookPreference</name> +<fan_out_visible value="0" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="0" level="0" /> +<fan_in_visible value="2" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="2" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>ManagerImpl</name> +<fan_out_visible value="0" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="0" level="0" /> +<fan_in_visible value="14" level="2" /> +<fan_in_concrete value="8" level="1" /> +<fan_in value="14" level="1" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>MappingNode</name> +<fan_out_visible value="6" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="6" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>NumberCleaner</name> +<fan_out_visible value="0" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="0" level="0" /> +<fan_in_visible value="1" level="0" /> +<fan_in_concrete value="1" level="0" /> +<fan_in value="1" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>Observer</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>Preferences</name> +<fan_out_visible value="0" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="0" level="0" /> +<fan_in_visible value="2" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="2" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>RegistrationState</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="1" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>ShortcutPreferences</name> +<fan_out_visible value="0" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="0" level="0" /> +<fan_in_visible value="3" level="0" /> +<fan_in_concrete value="1" level="0" /> +<fan_in value="3" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>Subject</name> +<fan_out_visible value="0" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="0" level="0" /> +<fan_in_visible value="1" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="1" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>TONEID</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="1" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>TokenList</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>VoIPLink</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="3" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="3" level="0" /> +<IF4_visible value="9" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="9" level="0" /> +</module> +<module> +<name>VoipPreference</name> +<fan_out_visible value="0" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="0" level="0" /> +<fan_in_visible value="2" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="2" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>YamlEmitter</name> +<fan_out_visible value="6" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="6" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>anonymous</name> +<fan_out_visible value="0" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="0" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>bool</name> +<fan_out_visible value="2" level="0" /> +<fan_out_concrete value="2" level="0" /> +<fan_out value="2" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>int32_t</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="0" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>map</name> +<fan_out_visible value="2" level="0" /> +<fan_out_concrete value="2" level="0" /> +<fan_out value="2" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>short</name> +<fan_out_visible value="1" level="0" /> +<fan_out_concrete value="1" level="0" /> +<fan_out value="1" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>string</name> +<fan_out_visible value="3" level="0" /> +<fan_out_concrete value="3" level="0" /> +<fan_out value="3" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +<module> +<name>vector</name> +<fan_out_visible value="2" level="0" /> +<fan_out_concrete value="1" level="0" /> +<fan_out value="2" level="0" /> +<fan_in_visible value="0" level="0" /> +<fan_in_concrete value="0" level="0" /> +<fan_in value="0" level="0" /> +<IF4_visible value="0" level="0" /> +<IF4_concrete value="0" level="0" /> +<IF4 value="0" level="0" /> +</module> +</structural_summary> +<other_extents> +<rejected_extent> +<name><file scope items></name> +<source_reference file="src/account.cpp" line="1" /> +<lines_of_code value="0" level="0" /> +<lines_of_comment value="0" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +</rejected_extent> +<rejected_extent> +<name><file scope items></name> +<source_reference file="src/accountcreator.cpp" line="1" /> +<lines_of_code value="2" level="0" /> +<lines_of_comment value="1" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +</rejected_extent> +<rejected_extent> +<name><file scope items></name> +<source_reference file="src/call.cpp" line="1" /> +<lines_of_code value="11" level="0" /> +<lines_of_comment value="1" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +</rejected_extent> +<rejected_extent> +<name><file scope items></name> +<source_reference file="src/conference.cpp" line="1" /> +<lines_of_code value="2" level="0" /> +<lines_of_comment value="30" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +</rejected_extent> +<rejected_extent> +<name><file scope items></name> +<source_reference file="src/eventthread.cpp" line="1" /> +<lines_of_code value="1" level="0" /> +<lines_of_comment value="1" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +</rejected_extent> +<rejected_extent> +<name><file scope items></name> +<source_reference file="src/logger.cpp" line="1" /> +<lines_of_code value="7" level="0" /> +<lines_of_comment value="29" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +</rejected_extent> +<rejected_extent> +<name><file scope items></name> +<source_reference file="src/main.cpp" line="1" /> +<lines_of_code value="4" level="0" /> +<lines_of_comment value="31" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +</rejected_extent> +<rejected_extent> +<name><file scope items></name> +<source_reference file="src/managerimpl.cpp" line="1" /> +<lines_of_code value="7" level="0" /> +<lines_of_comment value="1" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +</rejected_extent> +<rejected_extent> +<name><file scope items></name> +<source_reference file="src/managerimpl_registration.cpp" line="1" /> +<lines_of_code value="4" level="0" /> +<lines_of_comment value="35" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +</rejected_extent> +<rejected_extent> +<name><file scope items></name> +<source_reference file="src/numbercleaner.cpp" line="1" /> +<lines_of_code value="1" level="0" /> +<lines_of_comment value="1" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +</rejected_extent> +<rejected_extent> +<name><file scope items></name> +<source_reference file="src/observer.cpp" line="1" /> +<lines_of_code value="7" level="0" /> +<lines_of_comment value="30" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +</rejected_extent> +<rejected_extent> +<name><file scope items></name> +<source_reference file="src/preferences.cpp" line="1" /> +<lines_of_code value="1" level="0" /> +<lines_of_comment value="1" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +</rejected_extent> +<rejected_extent> +<name><file scope items></name> +<source_reference file="src/voiplink.cpp" line="1" /> +<lines_of_code value="1" level="0" /> +<lines_of_comment value="1" level="0" /> +<McCabes_cyclomatic_complexity value="0" level="0" /> +</rejected_extent> +</other_extents> +</CCCC_Project> diff --git a/sflphone-common/configure.ac b/sflphone-common/configure.ac index c7b986863833c2a13c6b93bd5245b9e8e9898ce1..80790e831c78ce5cfa501b981af9816eed31f0f5 100644 --- a/sflphone-common/configure.ac +++ b/sflphone-common/configure.ac @@ -266,9 +266,24 @@ fi xml_CFLAGS= xml_LIBS=-lexpat - AC_SUBST(xml_CFLAGS) +AC_SUBST(xml_CFLAGS) AC_SUBST(xml_LIBS) +AC_CHECK_LIB([yaml], yaml_parser_initialize, + [AC_CHECK_HEADERS(yaml.h, have_yaml=true, have_yaml=false)], + have_yaml = false) + + if test "$have_yaml" = "false"; then +AC_MSG_ERROR([You need the libyaml yaml parser] + [http://expat.sourceforge.net/]) + fi + +yaml_CFLAGS= +yaml_LIBS=-lyaml + +AC_SUBST(yaml_CFLAGS) +AC_SUBST(yaml_LIBS) + AC_CHECK_LIB([pthread], pthread_create, [AC_CHECK_HEADERS(pthread.h, have_pthread=true, have_pthread=false)], have_pthread=false) @@ -293,6 +308,7 @@ AC_SUBST(PCRE_CFLAGS) + # For the tools/, we need libdbus-c++ for the "build" architecture as well AM_CONDITIONAL(CROSS_COMPILING, test "$cross_compiling" = "yes") diff --git a/sflphone-common/globals.mak b/sflphone-common/globals.mak index 0c408d19286bdf59a1202bd2ccf87bb04ce3c928..16656d11a2b224e4893a497affd2bc629f55429d 100644 --- a/sflphone-common/globals.mak +++ b/sflphone-common/globals.mak @@ -1,10 +1,13 @@ # Global variables + +#CXXFLAGS=-Wall -Werror -Wextra + src=$(top_srcdir) sfllibdir=$(DESTDIR)$(libdir)/sflphone sflcodecdir=$(sfllibdir)/codecs sflplugindir=$(sfllibdir)/plugins -ASTYLERC="../astylerc" +ASTYLERC="$(top_srcdir)/../astylerc" indent="/usr/bin/astyle" # for pjsip @@ -66,3 +69,10 @@ AM_CPPFLAGS = \ -DENABLE_TRACE \ $(SPEEXCODEC) \ $(GSMCODEC) + + +indent: + @echo "Indenting code:" + if [ -f $(ASTYLERC) ] ; then \ + find $(top_srcdir)/src/ -regex ".*\.\(h\|cpp\)" -exec $(indent) --options=$(ASTYLERC) {} \; ; \ + fi diff --git a/sflphone-common/libs/dbus-c++/src/connection.cpp b/sflphone-common/libs/dbus-c++/src/connection.cpp index b7b6729726731f238347799ca5846b371b722fbb..0cc10df95143b90287770be421a87e8372ac3351 100644 --- a/sflphone-common/libs/dbus-c++/src/connection.cpp +++ b/sflphone-common/libs/dbus-c++/src/connection.cpp @@ -42,13 +42,11 @@ using namespace DBus; Connection::Private::Private (DBusConnection *c, Server::Private *s) - : conn (c) , dispatcher (0), server (s) -{ + : conn (c) , dispatcher (0), server (s) { init(); } -Connection::Private::Private (DBusBusType type) -{ +Connection::Private::Private (DBusBusType type) { InternalError e; conn = dbus_bus_get_private (type, e); @@ -58,8 +56,7 @@ Connection::Private::Private (DBusBusType type) init(); } -Connection::Private::~Private() -{ +Connection::Private::~Private() { debug_log ("terminating connection 0x%08x", conn); detach_server(); @@ -79,8 +76,7 @@ Connection::Private::~Private() dbus_connection_unref (conn); } -void Connection::Private::init() -{ +void Connection::Private::init() { dbus_connection_ref (conn); dbus_connection_ref (conn); //todo: the library has to own another reference @@ -94,8 +90,7 @@ void Connection::Private::init() dbus_connection_set_exit_on_disconnect (conn, false); //why was this set to true?? } -void Connection::Private::detach_server() -{ +void Connection::Private::detach_server() { /* Server::Private *tmp = server; server = NULL; @@ -115,8 +110,7 @@ void Connection::Private::detach_server() }*/ } -bool Connection::Private::do_dispatch() -{ +bool Connection::Private::do_dispatch() { debug_log ("dispatching on %p", conn); if (!dbus_connection_get_is_connected (conn)) { @@ -130,8 +124,7 @@ bool Connection::Private::do_dispatch() return dbus_connection_dispatch (conn) != DBUS_DISPATCH_DATA_REMAINS; } -void Connection::Private::dispatch_status_stub (DBusConnection *dc, DBusDispatchStatus status, void *data) -{ +void Connection::Private::dispatch_status_stub (DBusConnection *dc, DBusDispatchStatus status, void *data) { Private *p = static_cast<Private *> (data); switch (status) { @@ -151,8 +144,7 @@ void Connection::Private::dispatch_status_stub (DBusConnection *dc, DBusDispatch } } -DBusHandlerResult Connection::Private::message_filter_stub (DBusConnection *conn, DBusMessage *dmsg, void *data) -{ +DBusHandlerResult Connection::Private::message_filter_stub (DBusConnection *conn, DBusMessage *dmsg, void *data) { MessageSlot *slot = static_cast<MessageSlot *> (data); Message msg = Message (new Message::Private (dmsg)); @@ -162,8 +154,7 @@ DBusHandlerResult Connection::Private::message_filter_stub (DBusConnection *conn : DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -bool Connection::Private::disconn_filter_function (const Message &msg) -{ +bool Connection::Private::disconn_filter_function (const Message &msg) { if (msg.is_signal (DBUS_INTERFACE_LOCAL,"Disconnected")) { debug_log ("%p disconnected by local bus", conn); dbus_connection_close (conn); @@ -174,34 +165,28 @@ bool Connection::Private::disconn_filter_function (const Message &msg) return false; } -DBusDispatchStatus Connection::Private::dispatch_status() -{ +DBusDispatchStatus Connection::Private::dispatch_status() { return dbus_connection_get_dispatch_status (conn); } -bool Connection::Private::has_something_to_dispatch() -{ +bool Connection::Private::has_something_to_dispatch() { return dispatch_status() == DBUS_DISPATCH_DATA_REMAINS; } -Connection Connection::SystemBus() -{ +Connection Connection::SystemBus() { return Connection (new Private (DBUS_BUS_SYSTEM)); } -Connection Connection::SessionBus() -{ +Connection Connection::SessionBus() { return Connection (new Private (DBUS_BUS_SESSION)); } -Connection Connection::ActivationBus() -{ +Connection Connection::ActivationBus() { return Connection (new Private (DBUS_BUS_STARTER)); } -Connection::Connection (const char *address, bool priv) -{ +Connection::Connection (const char *address, bool priv) { InternalError e; DBusConnection *conn = priv ? dbus_connection_open_private (address, e) @@ -217,24 +202,20 @@ Connection::Connection (const char *address, bool priv) } Connection::Connection (Connection::Private *p) - : _pvt (p) -{ + : _pvt (p) { setup (default_dispatcher); } Connection::Connection (const Connection &c) - : _pvt (c._pvt) -{ + : _pvt (c._pvt) { dbus_connection_ref (_pvt->conn); } -Connection::~Connection() -{ +Connection::~Connection() { dbus_connection_unref (_pvt->conn); } -Dispatcher *Connection::setup (Dispatcher *dispatcher) -{ +Dispatcher *Connection::setup (Dispatcher *dispatcher) { debug_log ("registering stubs for connection %p", _pvt->conn); if (!dispatcher) dispatcher = default_dispatcher; @@ -268,13 +249,11 @@ Dispatcher *Connection::setup (Dispatcher *dispatcher) return prev; } -bool Connection::operator == (const Connection &c) const -{ +bool Connection::operator == (const Connection &c) const { return _pvt->conn == c._pvt->conn; } -bool Connection::register_bus() -{ +bool Connection::register_bus() { InternalError e; bool r = dbus_bus_register (_pvt->conn, e); @@ -284,39 +263,32 @@ bool Connection::register_bus() return r; } -bool Connection::connected() const -{ +bool Connection::connected() const { return dbus_connection_get_is_connected (_pvt->conn); } -void Connection::disconnect() -{ +void Connection::disconnect() { // dbus_connection_disconnect(_pvt->conn); // disappeared in 0.9x dbus_connection_close (_pvt->conn); } -void Connection::exit_on_disconnect (bool exit) -{ +void Connection::exit_on_disconnect (bool exit) { dbus_connection_set_exit_on_disconnect (_pvt->conn, exit); } -bool Connection::unique_name (const char *n) -{ +bool Connection::unique_name (const char *n) { return dbus_bus_set_unique_name (_pvt->conn, n); } -const char *Connection::unique_name() const -{ +const char *Connection::unique_name() const { return dbus_bus_get_unique_name (_pvt->conn); } -void Connection::flush() -{ +void Connection::flush() { dbus_connection_flush (_pvt->conn); } -void Connection::add_match (const char *rule) -{ +void Connection::add_match (const char *rule) { InternalError e; dbus_bus_add_match (_pvt->conn, rule, e); @@ -326,8 +298,7 @@ void Connection::add_match (const char *rule) if (e) throw Error (e); } -void Connection::remove_match (const char *rule) -{ +void Connection::remove_match (const char *rule) { InternalError e; dbus_bus_remove_match (_pvt->conn, rule, e); @@ -337,25 +308,21 @@ void Connection::remove_match (const char *rule) if (e) throw Error (e); } -bool Connection::add_filter (MessageSlot &s) -{ +bool Connection::add_filter (MessageSlot &s) { debug_log ("%s: adding filter", unique_name()); return dbus_connection_add_filter (_pvt->conn, Private::message_filter_stub, &s, NULL); } -void Connection::remove_filter (MessageSlot &s) -{ +void Connection::remove_filter (MessageSlot &s) { debug_log ("%s: removing filter", unique_name()); dbus_connection_remove_filter (_pvt->conn, Private::message_filter_stub, &s); } -bool Connection::send (const Message &msg, unsigned int *serial) -{ +bool Connection::send (const Message &msg, unsigned int *serial) { return dbus_connection_send (_pvt->conn, msg._pvt->msg, serial); } -Message Connection::send_blocking (Message &msg, int timeout) -{ +Message Connection::send_blocking (Message &msg, int timeout) { DBusMessage *reply; InternalError e; @@ -366,8 +333,7 @@ Message Connection::send_blocking (Message &msg, int timeout) return Message (new Message::Private (reply), false); } -PendingCall Connection::send_async (Message &msg, int timeout) -{ +PendingCall Connection::send_async (Message &msg, int timeout) { DBusPendingCall *pending; if (!dbus_connection_send_with_reply (_pvt->conn, msg._pvt->msg, &pending, timeout)) { @@ -377,8 +343,7 @@ PendingCall Connection::send_async (Message &msg, int timeout) return PendingCall (new PendingCall::Private (pending)); } -void Connection::request_name (const char *name, int flags) -{ +void Connection::request_name (const char *name, int flags) { InternalError e; debug_log ("%s: registering bus name %s", unique_name(), name); @@ -396,8 +361,7 @@ void Connection::request_name (const char *name, int flags) } } -unsigned long Connection::sender_unix_uid (const char *sender) -{ +unsigned long Connection::sender_unix_uid (const char *sender) { InternalError e; unsigned long ul = dbus_bus_get_unix_user (_pvt->conn, sender, e); @@ -407,8 +371,7 @@ unsigned long Connection::sender_unix_uid (const char *sender) return ul; } -bool Connection::has_name (const char *name) -{ +bool Connection::has_name (const char *name) { InternalError e; bool b = dbus_bus_name_has_owner (_pvt->conn, name, e); @@ -418,13 +381,11 @@ bool Connection::has_name (const char *name) return b; } -const std::vector<std::string>& Connection::names() -{ +const std::vector<std::string>& Connection::names() { return _pvt->names; } -bool Connection::start_service (const char *name, unsigned long flags) -{ +bool Connection::start_service (const char *name, unsigned long flags) { InternalError e; bool b = dbus_bus_start_service_by_name (_pvt->conn, name, flags, NULL, e); diff --git a/sflphone-common/libs/dbus-c++/src/debug.cpp b/sflphone-common/libs/dbus-c++/src/debug.cpp index 213a784d05a4a7672a86fc0825e8e0c83a4bdaf4..6ee5176ec5a2a77890980ee1023b4500744b6bfc 100644 --- a/sflphone-common/libs/dbus-c++/src/debug.cpp +++ b/sflphone-common/libs/dbus-c++/src/debug.cpp @@ -31,8 +31,7 @@ #include <cstdio> #include <stdlib.h> -static void _debug_log_default (const char *format, ...) -{ +static void _debug_log_default (const char *format, ...) { #ifdef DEBUG static int debug_env = getenv ("DBUSXX_VERBOSE") ? 1 : 0; diff --git a/sflphone-common/libs/dbus-c++/src/dispatcher.cpp b/sflphone-common/libs/dbus-c++/src/dispatcher.cpp index e71bae99fd48a0309d9f6f1c30e57bd3da8ee90e..b333f43a6f3c3cdff290e90c4109dd729c2f794a 100644 --- a/sflphone-common/libs/dbus-c++/src/dispatcher.cpp +++ b/sflphone-common/libs/dbus-c++/src/dispatcher.cpp @@ -38,23 +38,19 @@ DBus::Dispatcher *DBus::default_dispatcher = NULL; using namespace DBus; Timeout::Timeout (Timeout::Internal *i) - : _int (i) -{ + : _int (i) { dbus_timeout_set_data ( (DBusTimeout *) i, this, NULL); } -int Timeout::interval() const -{ +int Timeout::interval() const { return dbus_timeout_get_interval ( (DBusTimeout *) _int); } -bool Timeout::enabled() const -{ +bool Timeout::enabled() const { return dbus_timeout_get_enabled ( (DBusTimeout *) _int); } -bool Timeout::handle() -{ +bool Timeout::handle() { return dbus_timeout_handle ( (DBusTimeout *) _int); } @@ -62,13 +58,11 @@ bool Timeout::handle() */ Watch::Watch (Watch::Internal *i) - : _int (i) -{ + : _int (i) { dbus_watch_set_data ( (DBusWatch *) i, this, NULL); } -int Watch::descriptor() const -{ +int Watch::descriptor() const { #if HAVE_WIN32 return dbus_watch_get_socket ( (DBusWatch*) _int); #else @@ -76,26 +70,22 @@ int Watch::descriptor() const #endif } -int Watch::flags() const -{ +int Watch::flags() const { return dbus_watch_get_flags ( (DBusWatch *) _int); } -bool Watch::enabled() const -{ +bool Watch::enabled() const { return dbus_watch_get_enabled ( (DBusWatch *) _int); } -bool Watch::handle (int flags) -{ +bool Watch::handle (int flags) { return dbus_watch_handle ( (DBusWatch *) _int, flags); } /* */ -dbus_bool_t Dispatcher::Private::on_add_watch (DBusWatch *watch, void *data) -{ +dbus_bool_t Dispatcher::Private::on_add_watch (DBusWatch *watch, void *data) { Dispatcher *d = static_cast<Dispatcher *> (data); Watch::Internal *w = reinterpret_cast<Watch::Internal *> (watch); @@ -105,8 +95,7 @@ dbus_bool_t Dispatcher::Private::on_add_watch (DBusWatch *watch, void *data) return true; } -void Dispatcher::Private::on_rem_watch (DBusWatch *watch, void *data) -{ +void Dispatcher::Private::on_rem_watch (DBusWatch *watch, void *data) { Dispatcher *d = static_cast<Dispatcher *> (data); Watch *w = static_cast<Watch *> (dbus_watch_get_data (watch)); @@ -114,15 +103,13 @@ void Dispatcher::Private::on_rem_watch (DBusWatch *watch, void *data) d->rem_watch (w); } -void Dispatcher::Private::on_toggle_watch (DBusWatch *watch, void *data) -{ +void Dispatcher::Private::on_toggle_watch (DBusWatch *watch, void *data) { Watch *w = static_cast<Watch *> (dbus_watch_get_data (watch)); w->toggle(); } -dbus_bool_t Dispatcher::Private::on_add_timeout (DBusTimeout *timeout, void *data) -{ +dbus_bool_t Dispatcher::Private::on_add_timeout (DBusTimeout *timeout, void *data) { Dispatcher *d = static_cast<Dispatcher *> (data); Timeout::Internal *t = reinterpret_cast<Timeout::Internal *> (timeout); @@ -132,8 +119,7 @@ dbus_bool_t Dispatcher::Private::on_add_timeout (DBusTimeout *timeout, void *dat return true; } -void Dispatcher::Private::on_rem_timeout (DBusTimeout *timeout, void *data) -{ +void Dispatcher::Private::on_rem_timeout (DBusTimeout *timeout, void *data) { Dispatcher *d = static_cast<Dispatcher *> (data); Timeout *t = static_cast<Timeout *> (dbus_timeout_get_data (timeout)); @@ -141,23 +127,20 @@ void Dispatcher::Private::on_rem_timeout (DBusTimeout *timeout, void *data) d->rem_timeout (t); } -void Dispatcher::Private::on_toggle_timeout (DBusTimeout *timeout, void *data) -{ +void Dispatcher::Private::on_toggle_timeout (DBusTimeout *timeout, void *data) { Timeout *t = static_cast<Timeout *> (dbus_timeout_get_data (timeout)); t->toggle(); } -void Dispatcher::queue_connection (Connection::Private *cp) -{ +void Dispatcher::queue_connection (Connection::Private *cp) { _mutex_p.lock(); _pending_queue.push_back (cp); _mutex_p.unlock(); } -bool Dispatcher::has_something_to_dispatch() -{ +bool Dispatcher::has_something_to_dispatch() { _mutex_p.lock(); bool has_something = false; @@ -173,8 +156,7 @@ bool Dispatcher::has_something_to_dispatch() } -void Dispatcher::dispatch_pending() -{ +void Dispatcher::dispatch_pending() { _mutex_p.lock(); // SEEME: dbus-glib is dispatching only one message at a time to not starve the loop/other things... @@ -199,8 +181,7 @@ void Dispatcher::dispatch_pending() _mutex_p.unlock(); } -void DBus::_init_threading() -{ +void DBus::_init_threading() { #ifdef DBUS_HAS_THREADS_INIT_DEFAULT dbus_threads_init_default(); #else @@ -219,8 +200,7 @@ void DBus::_init_threading ( CondVarWaitTimeoutFn c4, CondVarWakeOneFn c5, CondVarWakeAllFn c6 -) -{ +) { #ifndef DBUS_HAS_RECURSIVE_MUTEX DBusThreadFunctions functions = { DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK | diff --git a/sflphone-common/libs/dbus-c++/src/ecore-integration.cpp b/sflphone-common/libs/dbus-c++/src/ecore-integration.cpp index d18d4b1136cc2b43de1f4eaa22841cb4fb4c8f80..d18192f279c12879883cf0b38bc53da646480d6b 100644 --- a/sflphone-common/libs/dbus-c++/src/ecore-integration.cpp +++ b/sflphone-common/libs/dbus-c++/src/ecore-integration.cpp @@ -32,26 +32,22 @@ using namespace DBus; Ecore::BusTimeout::BusTimeout (Timeout::Internal* ti) - : Timeout (ti) -{ + : Timeout (ti) { _enable(); } -Ecore::BusTimeout::~BusTimeout() -{ +Ecore::BusTimeout::~BusTimeout() { _disable(); } -void Ecore::BusTimeout::toggle() -{ +void Ecore::BusTimeout::toggle() { debug_log ("ecore: timeout %p toggled (%s)", this, Timeout::enabled() ? "on":"off"); if (Timeout::enabled()) _enable(); else _disable(); } -int Ecore::BusTimeout::timeout_handler (void *data) -{ +int Ecore::BusTimeout::timeout_handler (void *data) { Ecore::BusTimeout* t = reinterpret_cast<Ecore::BusTimeout*> (data); debug_log ("Ecore::BusTimeout::timeout_handler( void *data )"); @@ -61,37 +57,32 @@ int Ecore::BusTimeout::timeout_handler (void *data) return 1; // 1 -> reshedule in ecore for next timer interval } -void Ecore::BusTimeout::_enable() -{ +void Ecore::BusTimeout::_enable() { debug_log ("Ecore::BusTimeout::_enable()"); _etimer = ecore_timer_add ( ( (double) Timeout::interval()) /1000, timeout_handler, this); } -void Ecore::BusTimeout::_disable() -{ +void Ecore::BusTimeout::_disable() { debug_log ("Ecore::BusTimeout::_disable()"); ecore_timer_del (_etimer); } -static bool watch_prepare (int *timeout) -{ +static bool watch_prepare (int *timeout) { debug_log ("ecore: watch_prepare"); *timeout = -1; return false; } -static bool watch_check() -{ +static bool watch_check() { debug_log ("ecore: watch_check"); return true; } -static bool watch_dispatch (void *data) -{ +static bool watch_dispatch (void *data) { debug_log ("ecore: watch_dispatch"); bool cb = true; @@ -100,26 +91,22 @@ static bool watch_dispatch (void *data) } Ecore::BusWatch::BusWatch (Watch::Internal* wi) - : Watch (wi) -{ + : Watch (wi) { _enable(); } -Ecore::BusWatch::~BusWatch() -{ +Ecore::BusWatch::~BusWatch() { _disable(); } -void Ecore::BusWatch::toggle() -{ +void Ecore::BusWatch::toggle() { debug_log ("ecore: watch %p toggled (%s)", this, Watch::enabled() ? "on":"off"); if (Watch::enabled()) _enable(); else _disable(); } -int Ecore::BusWatch::watch_handler_read (void *data, Ecore_Fd_Handler *fdh) -{ +int Ecore::BusWatch::watch_handler_read (void *data, Ecore_Fd_Handler *fdh) { Ecore::BusWatch* w = reinterpret_cast<Ecore::BusWatch*> (data); debug_log ("ecore: watch_handler_read"); @@ -133,8 +120,7 @@ int Ecore::BusWatch::watch_handler_read (void *data, Ecore_Fd_Handler *fdh) return 1; } -int Ecore::BusWatch::watch_handler_error (void *data, Ecore_Fd_Handler *fdh) -{ +int Ecore::BusWatch::watch_handler_error (void *data, Ecore_Fd_Handler *fdh) { Ecore::BusWatch* w = reinterpret_cast<Ecore::BusWatch*> (data); debug_log ("ecore: watch_handler_error"); @@ -146,8 +132,7 @@ int Ecore::BusWatch::watch_handler_error (void *data, Ecore_Fd_Handler *fdh) return 1; } -void Ecore::BusWatch::_enable() -{ +void Ecore::BusWatch::_enable() { debug_log ("Ecore::BusWatch::_enable()"); int flags = Watch::flags(); @@ -169,18 +154,15 @@ void Ecore::BusWatch::_enable() ecore_main_fd_handler_active_set (fd_handler_error, ECORE_FD_ERROR); } -void Ecore::BusWatch::_disable() -{ +void Ecore::BusWatch::_disable() { ecore_main_fd_handler_del (fd_handler_read); ecore_main_fd_handler_del (fd_handler_error); } -void Ecore::BusDispatcher::attach() -{ +void Ecore::BusDispatcher::attach() { } -Timeout* Ecore::BusDispatcher::add_timeout (Timeout::Internal* wi) -{ +Timeout* Ecore::BusDispatcher::add_timeout (Timeout::Internal* wi) { Timeout* t = new Ecore::BusTimeout (wi); debug_log ("ecore: added timeout %p (%s)", t, t->enabled() ? "on":"off"); @@ -188,15 +170,13 @@ Timeout* Ecore::BusDispatcher::add_timeout (Timeout::Internal* wi) return t; } -void Ecore::BusDispatcher::rem_timeout (Timeout* t) -{ +void Ecore::BusDispatcher::rem_timeout (Timeout* t) { debug_log ("ecore: removed timeout %p", t); delete t; } -Watch* Ecore::BusDispatcher::add_watch (Watch::Internal* wi) -{ +Watch* Ecore::BusDispatcher::add_watch (Watch::Internal* wi) { Watch* w = new Ecore::BusWatch (wi); debug_log ("ecore: added watch %p (%s) fd=%d flags=%d", @@ -205,8 +185,7 @@ Watch* Ecore::BusDispatcher::add_watch (Watch::Internal* wi) return w; } -void Ecore::BusDispatcher::rem_watch (Watch* w) -{ +void Ecore::BusDispatcher::rem_watch (Watch* w) { debug_log ("ecore: removed watch %p", w); delete w; diff --git a/sflphone-common/libs/dbus-c++/src/error.cpp b/sflphone-common/libs/dbus-c++/src/error.cpp index 5b95d58fa8aa00d37acce238384824b90e052f7b..ccb3da960fec2d0ace11c4e860d07cc69a15c3af 100644 --- a/sflphone-common/libs/dbus-c++/src/error.cpp +++ b/sflphone-common/libs/dbus-c++/src/error.cpp @@ -45,43 +45,35 @@ Error::Error (InternalError &i) : _int (new InternalError (i)) {} Error::Error (const char *name, const char *message) - : _int (new InternalError) -{ + : _int (new InternalError) { set (name, message); } Error::Error (Message &m) - : _int (new InternalError) -{ + : _int (new InternalError) { dbus_set_error_from_message (& (_int->error), m._pvt->msg); } -Error::~Error() throw() -{ +Error::~Error() throw() { } -const char *Error::name() const -{ +const char *Error::name() const { return _int->error.name; } -const char *Error::message() const -{ +const char *Error::message() const { return _int->error.message; } -bool Error::is_set() const -{ +bool Error::is_set() const { return * (_int); } -void Error::set (const char *name, const char *message) -{ +void Error::set (const char *name, const char *message) { dbus_set_error_const (& (_int->error), name, message); } -const char *Error::what() const throw() -{ +const char *Error::what() const throw() { return _int->error.message; } diff --git a/sflphone-common/libs/dbus-c++/src/eventloop-integration.cpp b/sflphone-common/libs/dbus-c++/src/eventloop-integration.cpp index 6947f28130fa5d27e4b83038246626c0a1b1ba9a..f367623e5f5b9fb887d5ff86fb0885fe295e062e 100644 --- a/sflphone-common/libs/dbus-c++/src/eventloop-integration.cpp +++ b/sflphone-common/libs/dbus-c++/src/eventloop-integration.cpp @@ -35,21 +35,18 @@ using namespace DBus; BusTimeout::BusTimeout (Timeout::Internal *ti, BusDispatcher *bd) - : Timeout (ti), DefaultTimeout (Timeout::interval(), true, bd) -{ + : Timeout (ti), DefaultTimeout (Timeout::interval(), true, bd) { DefaultTimeout::enabled (Timeout::enabled()); } -void BusTimeout::toggle() -{ +void BusTimeout::toggle() { debug_log ("timeout %p toggled (%s)", this, Timeout::enabled() ? "on":"off"); DefaultTimeout::enabled (Timeout::enabled()); } BusWatch::BusWatch (Watch::Internal *wi, BusDispatcher *bd) - : Watch (wi), DefaultWatch (Watch::descriptor(), 0, bd) -{ + : Watch (wi), DefaultWatch (Watch::descriptor(), 0, bd) { int flags = POLLHUP | POLLERR; if (Watch::flags() & DBUS_WATCH_READABLE) @@ -63,15 +60,13 @@ BusWatch::BusWatch (Watch::Internal *wi, BusDispatcher *bd) DefaultWatch::enabled (Watch::enabled()); } -void BusWatch::toggle() -{ +void BusWatch::toggle() { debug_log ("watch %p toggled (%s)", this, Watch::enabled() ? "on":"off"); DefaultWatch::enabled (Watch::enabled()); } -void BusDispatcher::enter() -{ +void BusDispatcher::enter() { debug_log ("entering dispatcher %p", this); _running = true; @@ -83,20 +78,17 @@ void BusDispatcher::enter() debug_log ("leaving dispatcher %p", this); } -void BusDispatcher::leave() -{ +void BusDispatcher::leave() { _running = false; terminate(); } -void BusDispatcher::do_iteration() -{ +void BusDispatcher::do_iteration() { dispatch_pending(); dispatch(); } -Timeout *BusDispatcher::add_timeout (Timeout::Internal *ti) -{ +Timeout *BusDispatcher::add_timeout (Timeout::Internal *ti) { BusTimeout *bt = new BusTimeout (ti, this); bt->expired = new Callback<BusDispatcher, void, DefaultTimeout &> (this, &BusDispatcher::timeout_expired); @@ -108,15 +100,13 @@ Timeout *BusDispatcher::add_timeout (Timeout::Internal *ti) return bt; } -void BusDispatcher::rem_timeout (Timeout *t) -{ +void BusDispatcher::rem_timeout (Timeout *t) { debug_log ("removed timeout %p", t); delete t; } -Watch *BusDispatcher::add_watch (Watch::Internal *wi) -{ +Watch *BusDispatcher::add_watch (Watch::Internal *wi) { BusWatch *bw = new BusWatch (wi, this); bw->ready = new Callback<BusDispatcher, void, DefaultWatch &> (this, &BusDispatcher::watch_ready); @@ -128,15 +118,13 @@ Watch *BusDispatcher::add_watch (Watch::Internal *wi) return bw; } -void BusDispatcher::rem_watch (Watch *w) -{ +void BusDispatcher::rem_watch (Watch *w) { debug_log ("removed watch %p", w); delete w; } -void BusDispatcher::timeout_expired (DefaultTimeout &et) -{ +void BusDispatcher::timeout_expired (DefaultTimeout &et) { debug_log ("timeout %p expired", &et); BusTimeout *timeout = reinterpret_cast<BusTimeout *> (et.data()); @@ -144,8 +132,7 @@ void BusDispatcher::timeout_expired (DefaultTimeout &et) timeout->handle(); } -void BusDispatcher::watch_ready (DefaultWatch &ew) -{ +void BusDispatcher::watch_ready (DefaultWatch &ew) { BusWatch *watch = reinterpret_cast<BusWatch *> (ew.data()); debug_log ("watch %p ready, flags=%d state=%d", diff --git a/sflphone-common/libs/dbus-c++/src/eventloop.cpp b/sflphone-common/libs/dbus-c++/src/eventloop.cpp index f74cafeaa6385fb66bf45d96f64315c25f3ec0a8..94bf59b389069754f9d6a016a717d6abac8b0e1d 100644 --- a/sflphone-common/libs/dbus-c++/src/eventloop.cpp +++ b/sflphone-common/libs/dbus-c++/src/eventloop.cpp @@ -36,14 +36,12 @@ using namespace DBus; -static double millis (timeval tv) -{ +static double millis (timeval tv) { return (tv.tv_sec *1000.0 + tv.tv_usec/1000.0); } DefaultTimeout::DefaultTimeout (int interval, bool repeat, DefaultMainLoop *ed) - : _enabled (true), _interval (interval), _repeat (repeat), _expiration (0), _data (0), _disp (ed) -{ + : _enabled (true), _interval (interval), _repeat (repeat), _expiration (0), _data (0), _disp (ed) { timeval now; gettimeofday (&now, NULL); @@ -54,57 +52,48 @@ DefaultTimeout::DefaultTimeout (int interval, bool repeat, DefaultMainLoop *ed) _disp->_mutex_t.unlock(); } -DefaultTimeout::~DefaultTimeout() -{ +DefaultTimeout::~DefaultTimeout() { _disp->_mutex_t.lock(); _disp->_timeouts.remove (this); _disp->_mutex_t.unlock(); } DefaultWatch::DefaultWatch (int fd, int flags, DefaultMainLoop *ed) - : _enabled (true), _fd (fd), _flags (flags), _state (0), _data (0), _disp (ed) -{ + : _enabled (true), _fd (fd), _flags (flags), _state (0), _data (0), _disp (ed) { _disp->_mutex_w.lock(); _disp->_watches.push_back (this); _disp->_mutex_w.unlock(); } -DefaultWatch::~DefaultWatch() -{ +DefaultWatch::~DefaultWatch() { _disp->_mutex_w.lock(); _disp->_watches.remove (this); _disp->_mutex_w.unlock(); } -DefaultMutex::DefaultMutex() -{ +DefaultMutex::DefaultMutex() { pthread_mutex_init (&_mutex, NULL); } -DefaultMutex::~DefaultMutex() -{ +DefaultMutex::~DefaultMutex() { pthread_mutex_destroy (&_mutex); } -void DefaultMutex::lock() -{ +void DefaultMutex::lock() { pthread_mutex_lock (&_mutex); } -void DefaultMutex::unlock() -{ +void DefaultMutex::unlock() { pthread_mutex_unlock (&_mutex); } -DefaultMainLoop::DefaultMainLoop() -{ +DefaultMainLoop::DefaultMainLoop() { if (pipe (_terminateFd) < 0) { throw ErrorFailed ("unable to create unamed pipe"); } } -DefaultMainLoop::~DefaultMainLoop() -{ +DefaultMainLoop::~DefaultMainLoop() { _mutex_w.lock(); DefaultWatches::iterator wi = _watches.begin(); @@ -140,13 +129,11 @@ DefaultMainLoop::~DefaultMainLoop() _mutex_t.unlock(); } -void DefaultMainLoop::terminate() -{ +void DefaultMainLoop::terminate() { write (_terminateFd[1], " ", 1); } -void DefaultMainLoop::dispatch() -{ +void DefaultMainLoop::dispatch() { _mutex_w.lock(); int nfd = _watches.size() + 1; diff --git a/sflphone-common/libs/dbus-c++/src/glib-integration.cpp b/sflphone-common/libs/dbus-c++/src/glib-integration.cpp index 1739670bfc49bb7eaa79ed55b8113caf5a161d39..8785608fa7f15b5c507d9fb576492ab4b00a56c3 100644 --- a/sflphone-common/libs/dbus-c++/src/glib-integration.cpp +++ b/sflphone-common/libs/dbus-c++/src/glib-integration.cpp @@ -31,27 +31,23 @@ using namespace DBus; Glib::BusTimeout::BusTimeout (Timeout::Internal *ti, GMainContext *ctx, int priority) - : Timeout (ti), _ctx (ctx), _priority (priority), _source (NULL) -{ + : Timeout (ti), _ctx (ctx), _priority (priority), _source (NULL) { if (Timeout::enabled()) _enable(); } -Glib::BusTimeout::~BusTimeout() -{ +Glib::BusTimeout::~BusTimeout() { _disable(); } -void Glib::BusTimeout::toggle() -{ +void Glib::BusTimeout::toggle() { debug_log ("glib: timeout %p toggled (%s)", this, Timeout::enabled() ? "on":"off"); if (Timeout::enabled()) _enable(); else _disable(); } -gboolean Glib::BusTimeout::timeout_handler (gpointer data) -{ +gboolean Glib::BusTimeout::timeout_handler (gpointer data) { Glib::BusTimeout *t = reinterpret_cast<Glib::BusTimeout *> (data); t->handle(); @@ -59,8 +55,7 @@ gboolean Glib::BusTimeout::timeout_handler (gpointer data) return TRUE; } -void Glib::BusTimeout::_enable() -{ +void Glib::BusTimeout::_enable() { if (_source) _disable(); // be sane @@ -73,8 +68,7 @@ void Glib::BusTimeout::_enable() g_source_attach (_source, _ctx); } -void Glib::BusTimeout::_disable() -{ +void Glib::BusTimeout::_disable() { if (_source) { g_source_destroy (_source); _source = NULL; @@ -86,24 +80,21 @@ struct BusSource { GPollFD poll; }; -static gboolean watch_prepare (GSource *source, gint *timeout) -{ +static gboolean watch_prepare (GSource *source, gint *timeout) { //debug_log("glib: watch_prepare"); *timeout = -1; return FALSE; } -static gboolean watch_check (GSource *source) -{ +static gboolean watch_check (GSource *source) { //debug_log("glib: watch_check"); BusSource *io = (BusSource *) source; return io->poll.revents ? TRUE : FALSE; } -static gboolean watch_dispatch (GSource *source, GSourceFunc callback, gpointer data) -{ +static gboolean watch_dispatch (GSource *source, GSourceFunc callback, gpointer data) { debug_log ("glib: watch_dispatch"); gboolean cb = callback (data); @@ -118,27 +109,23 @@ static GSourceFuncs watch_funcs = { }; Glib::BusWatch::BusWatch (Watch::Internal *wi, GMainContext *ctx, int priority) - : Watch (wi), _ctx (ctx), _priority (priority), _source (NULL) -{ + : Watch (wi), _ctx (ctx), _priority (priority), _source (NULL) { if (Watch::enabled()) _enable(); } -Glib::BusWatch::~BusWatch() -{ +Glib::BusWatch::~BusWatch() { _disable(); } -void Glib::BusWatch::toggle() -{ +void Glib::BusWatch::toggle() { debug_log ("glib: watch %p toggled (%s)", this, Watch::enabled() ? "on":"off"); if (Watch::enabled()) _enable(); else _disable(); } -gboolean Glib::BusWatch::watch_handler (gpointer data) -{ +gboolean Glib::BusWatch::watch_handler (gpointer data) { Glib::BusWatch *w = reinterpret_cast<Glib::BusWatch *> (data); BusSource *io = (BusSource *) (w->_source); @@ -162,8 +149,7 @@ gboolean Glib::BusWatch::watch_handler (gpointer data) return TRUE; } -void Glib::BusWatch::_enable() -{ +void Glib::BusWatch::_enable() { if (_source) _disable(); // be sane @@ -202,8 +188,7 @@ void Glib::BusWatch::_enable() g_source_attach (_source, _ctx); } -void Glib::BusWatch::_disable() -{ +void Glib::BusWatch::_disable() { if (!_source) return; @@ -228,8 +213,7 @@ struct DispatcherSource { }; -static gboolean dispatcher_prepare (GSource *source, gint *timeout) -{ +static gboolean dispatcher_prepare (GSource *source, gint *timeout) { Dispatcher *dispatcher = ( (DispatcherSource*) source)->dispatcher; *timeout = -1; @@ -237,16 +221,14 @@ static gboolean dispatcher_prepare (GSource *source, gint *timeout) return dispatcher->has_something_to_dispatch() ? TRUE:FALSE; } -static gboolean dispatcher_check (GSource *source) -{ +static gboolean dispatcher_check (GSource *source) { return FALSE; } static gboolean dispatcher_dispatch (GSource *source, GSourceFunc callback, - gpointer user_data) -{ + gpointer user_data) { Dispatcher *dispatcher = ( (DispatcherSource*) source)->dispatcher; dispatcher->dispatch_pending(); @@ -261,12 +243,10 @@ static const GSourceFuncs dispatcher_funcs = { }; Glib::BusDispatcher::BusDispatcher() - : _ctx (NULL), _priority (G_PRIORITY_DEFAULT), _source (NULL) -{ + : _ctx (NULL), _priority (G_PRIORITY_DEFAULT), _source (NULL) { } -Glib::BusDispatcher::~BusDispatcher() -{ +Glib::BusDispatcher::~BusDispatcher() { if (_source) { GSource *temp = _source; _source = NULL; @@ -279,8 +259,7 @@ Glib::BusDispatcher::~BusDispatcher() g_main_context_unref (_ctx); } -void Glib::BusDispatcher::attach (GMainContext *ctx) -{ +void Glib::BusDispatcher::attach (GMainContext *ctx) { g_assert (_ctx == NULL); // just to be sane _ctx = ctx ? ctx : g_main_context_default(); @@ -294,8 +273,7 @@ void Glib::BusDispatcher::attach (GMainContext *ctx) g_source_attach (_source, _ctx); } -Timeout *Glib::BusDispatcher::add_timeout (Timeout::Internal *wi) -{ +Timeout *Glib::BusDispatcher::add_timeout (Timeout::Internal *wi) { Timeout *t = new Glib::BusTimeout (wi, _ctx, _priority); debug_log ("glib: added timeout %p (%s)", t, t->enabled() ? "on":"off"); @@ -303,15 +281,13 @@ Timeout *Glib::BusDispatcher::add_timeout (Timeout::Internal *wi) return t; } -void Glib::BusDispatcher::rem_timeout (Timeout *t) -{ +void Glib::BusDispatcher::rem_timeout (Timeout *t) { debug_log ("glib: removed timeout %p", t); delete t; } -Watch *Glib::BusDispatcher::add_watch (Watch::Internal *wi) -{ +Watch *Glib::BusDispatcher::add_watch (Watch::Internal *wi) { Watch *w = new Glib::BusWatch (wi, _ctx, _priority); debug_log ("glib: added watch %p (%s) fd=%d flags=%d", @@ -320,14 +296,12 @@ Watch *Glib::BusDispatcher::add_watch (Watch::Internal *wi) return w; } -void Glib::BusDispatcher::rem_watch (Watch *w) -{ +void Glib::BusDispatcher::rem_watch (Watch *w) { debug_log ("glib: removed watch %p", w); delete w; } -void Glib::BusDispatcher::set_priority (int priority) -{ +void Glib::BusDispatcher::set_priority (int priority) { _priority = priority; } diff --git a/sflphone-common/libs/dbus-c++/src/interface.cpp b/sflphone-common/libs/dbus-c++/src/interface.cpp index ca5202f2ffafeb95e07af424b6d984c9ba25278b..95c11efdc41ff5f0e739c00307f7a2c13e7a759c 100644 --- a/sflphone-common/libs/dbus-c++/src/interface.cpp +++ b/sflphone-common/libs/dbus-c++/src/interface.cpp @@ -37,23 +37,20 @@ Interface::Interface (const std::string &name) Interface::~Interface() {} -InterfaceAdaptor *AdaptorBase::find_interface (const std::string &name) -{ +InterfaceAdaptor *AdaptorBase::find_interface (const std::string &name) { InterfaceAdaptorTable::const_iterator ii = _interfaces.find (name); return ii != _interfaces.end() ? ii->second : NULL; } InterfaceAdaptor::InterfaceAdaptor (const std::string &name) - : Interface (name) -{ + : Interface (name) { debug_log ("adding interface %s", name.c_str()); _interfaces[name] = this; } -Message InterfaceAdaptor::dispatch_method (const CallMessage &msg) -{ +Message InterfaceAdaptor::dispatch_method (const CallMessage &msg) { const char *name = msg.member(); MethodTable::iterator mi = _methods.find (name); @@ -65,8 +62,7 @@ Message InterfaceAdaptor::dispatch_method (const CallMessage &msg) } } -void InterfaceAdaptor::emit_signal (const SignalMessage &sig) -{ +void InterfaceAdaptor::emit_signal (const SignalMessage &sig) { SignalMessage &sig2 = const_cast<SignalMessage &> (sig); if (sig2.interface() == NULL) @@ -75,8 +71,7 @@ void InterfaceAdaptor::emit_signal (const SignalMessage &sig) _emit_signal (sig2); } -Variant *InterfaceAdaptor::get_property (const std::string &name) -{ +Variant *InterfaceAdaptor::get_property (const std::string &name) { PropertyTable::iterator pti = _properties.find (name); if (pti != _properties.end()) { @@ -89,8 +84,7 @@ Variant *InterfaceAdaptor::get_property (const std::string &name) return NULL; } -void InterfaceAdaptor::set_property (const std::string &name, Variant &value) -{ +void InterfaceAdaptor::set_property (const std::string &name, Variant &value) { PropertyTable::iterator pti = _properties.find (name); if (pti != _properties.end()) { @@ -110,23 +104,20 @@ void InterfaceAdaptor::set_property (const std::string &name, Variant &value) throw ErrorFailed ("requested property not found"); } -InterfaceProxy *ProxyBase::find_interface (const std::string &name) -{ +InterfaceProxy *ProxyBase::find_interface (const std::string &name) { InterfaceProxyTable::const_iterator ii = _interfaces.find (name); return ii != _interfaces.end() ? ii->second : NULL; } InterfaceProxy::InterfaceProxy (const std::string &name) - : Interface (name) -{ + : Interface (name) { debug_log ("adding interface %s", name.c_str()); _interfaces[name] = this; } -bool InterfaceProxy::dispatch_signal (const SignalMessage &msg) -{ +bool InterfaceProxy::dispatch_signal (const SignalMessage &msg) { const char *name = msg.member(); SignalTable::iterator si = _signals.find (name); @@ -143,8 +134,7 @@ bool InterfaceProxy::dispatch_signal (const SignalMessage &msg) } } -Message InterfaceProxy::invoke_method (const CallMessage &call) -{ +Message InterfaceProxy::invoke_method (const CallMessage &call) { CallMessage &call2 = const_cast<CallMessage &> (call); if (call.interface() == NULL) @@ -153,8 +143,7 @@ Message InterfaceProxy::invoke_method (const CallMessage &call) return _invoke_method (call2); } -bool InterfaceProxy::invoke_method_noreply (const CallMessage &call) -{ +bool InterfaceProxy::invoke_method_noreply (const CallMessage &call) { CallMessage &call2 = const_cast<CallMessage &> (call); if (call.interface() == NULL) diff --git a/sflphone-common/libs/dbus-c++/src/introspection.cpp b/sflphone-common/libs/dbus-c++/src/introspection.cpp index 666c6e5cc5f0d2891dd4555008547e1f51950429..15eb5fcc0df143c64b8bc287d0e8163e36b575a3 100644 --- a/sflphone-common/libs/dbus-c++/src/introspection.cpp +++ b/sflphone-common/libs/dbus-c++/src/introspection.cpp @@ -38,13 +38,11 @@ using namespace DBus; static const char *introspectable_name = "org.freedesktop.DBus.Introspectable"; IntrospectableAdaptor::IntrospectableAdaptor() - : InterfaceAdaptor (introspectable_name) -{ + : InterfaceAdaptor (introspectable_name) { register_method (IntrospectableAdaptor, Introspect, Introspect); } -Message IntrospectableAdaptor::Introspect (const CallMessage &call) -{ +Message IntrospectableAdaptor::Introspect (const CallMessage &call) { debug_log ("requested introspection data"); std::ostringstream xml; @@ -143,8 +141,7 @@ Message IntrospectableAdaptor::Introspect (const CallMessage &call) return reply; } -IntrospectedInterface *const IntrospectableAdaptor::introspect() const -{ +IntrospectedInterface *const IntrospectableAdaptor::introspect() const { static IntrospectedArgument Introspect_args[] = { { "data", "s", false }, { 0, 0, 0 } @@ -171,8 +168,7 @@ IntrospectedInterface *const IntrospectableAdaptor::introspect() const IntrospectableProxy::IntrospectableProxy() : InterfaceProxy (introspectable_name) {} -std::string IntrospectableProxy::Introspect() -{ +std::string IntrospectableProxy::Introspect() { DBus::CallMessage call; call.member ("Introspect"); diff --git a/sflphone-common/libs/dbus-c++/src/message.cpp b/sflphone-common/libs/dbus-c++/src/message.cpp index 4c1c5e2a7160c85bac2a082b31b2a503b40850f4..741aab5a19a019fb2dea7bfce5901f078d50e1d0 100644 --- a/sflphone-common/libs/dbus-c++/src/message.cpp +++ b/sflphone-common/libs/dbus-c++/src/message.cpp @@ -38,233 +38,194 @@ using namespace DBus; /* */ -int MessageIter::type() -{ +int MessageIter::type() { return dbus_message_iter_get_arg_type ( (DBusMessageIter *) &_iter); } -bool MessageIter::at_end() -{ +bool MessageIter::at_end() { return type() == DBUS_TYPE_INVALID; } -bool MessageIter::has_next() -{ +bool MessageIter::has_next() { return dbus_message_iter_has_next ( (DBusMessageIter *) &_iter); } -MessageIter &MessageIter::operator ++() -{ +MessageIter &MessageIter::operator ++() { dbus_message_iter_next ( (DBusMessageIter *) &_iter); return (*this); } -MessageIter MessageIter::operator ++ (int) -{ +MessageIter MessageIter::operator ++ (int) { MessageIter copy (*this); ++ (*this); return copy; } -bool MessageIter::append_basic (int type_id, void *value) -{ +bool MessageIter::append_basic (int type_id, void *value) { return dbus_message_iter_append_basic ( (DBusMessageIter *) &_iter, type_id, value); } -void MessageIter::get_basic (int type_id, void *ptr) -{ +void MessageIter::get_basic (int type_id, void *ptr) { if (type() != type_id) throw ErrorInvalidArgs ("type mismatch"); dbus_message_iter_get_basic ( (DBusMessageIter *) _iter, ptr); } -bool MessageIter::append_byte (unsigned char b) -{ +bool MessageIter::append_byte (unsigned char b) { return append_basic (DBUS_TYPE_BYTE, &b); } -unsigned char MessageIter::get_byte() -{ +unsigned char MessageIter::get_byte() { unsigned char b; get_basic (DBUS_TYPE_BYTE, &b); return b; } -bool MessageIter::append_bool (bool b) -{ +bool MessageIter::append_bool (bool b) { dbus_bool_t db = b; return append_basic (DBUS_TYPE_BOOLEAN, &db); } -bool MessageIter::get_bool() -{ +bool MessageIter::get_bool() { dbus_bool_t db; get_basic (DBUS_TYPE_BOOLEAN, &db); return (bool) db; } -bool MessageIter::append_int16 (signed short i) -{ +bool MessageIter::append_int16 (signed short i) { return append_basic (DBUS_TYPE_INT16, &i); } -signed short MessageIter::get_int16() -{ +signed short MessageIter::get_int16() { signed short i; get_basic (DBUS_TYPE_INT16, &i); return i; } -bool MessageIter::append_uint16 (unsigned short u) -{ +bool MessageIter::append_uint16 (unsigned short u) { return append_basic (DBUS_TYPE_UINT16, &u); } -unsigned short MessageIter::get_uint16() -{ +unsigned short MessageIter::get_uint16() { unsigned short u; get_basic (DBUS_TYPE_UINT16, &u); return u; } -bool MessageIter::append_int32 (signed int i) -{ +bool MessageIter::append_int32 (signed int i) { return append_basic (DBUS_TYPE_INT32, &i); } -signed int MessageIter::get_int32() -{ +signed int MessageIter::get_int32() { signed int i; get_basic (DBUS_TYPE_INT32, &i); return i; } -bool MessageIter::append_uint32 (unsigned int u) -{ +bool MessageIter::append_uint32 (unsigned int u) { return append_basic (DBUS_TYPE_UINT32, &u); } -unsigned int MessageIter::get_uint32() -{ +unsigned int MessageIter::get_uint32() { unsigned int u; get_basic (DBUS_TYPE_UINT32, &u); return u; } -signed long long MessageIter::get_int64() -{ +signed long long MessageIter::get_int64() { signed long long i; get_basic (DBUS_TYPE_INT64, &i); return i; } -bool MessageIter::append_int64 (signed long long i) -{ +bool MessageIter::append_int64 (signed long long i) { return append_basic (DBUS_TYPE_INT64, &i); } -unsigned long long MessageIter::get_uint64() -{ +unsigned long long MessageIter::get_uint64() { unsigned long long u; get_basic (DBUS_TYPE_UINT64, &u); return u; } -bool MessageIter::append_uint64 (unsigned long long u) -{ +bool MessageIter::append_uint64 (unsigned long long u) { return append_basic (DBUS_TYPE_UINT64, &u); } -double MessageIter::get_double() -{ +double MessageIter::get_double() { double d; get_basic (DBUS_TYPE_DOUBLE, &d); return d; } -bool MessageIter::append_double (double d) -{ +bool MessageIter::append_double (double d) { return append_basic (DBUS_TYPE_DOUBLE, &d); } -bool MessageIter::append_string (const char *chars) -{ +bool MessageIter::append_string (const char *chars) { return append_basic (DBUS_TYPE_STRING, &chars); } -const char *MessageIter::get_string() -{ +const char *MessageIter::get_string() { char *chars; get_basic (DBUS_TYPE_STRING, &chars); return chars; } -bool MessageIter::append_path (const char *chars) -{ +bool MessageIter::append_path (const char *chars) { return append_basic (DBUS_TYPE_OBJECT_PATH, &chars); } -const char *MessageIter::get_path() -{ +const char *MessageIter::get_path() { char *chars; get_basic (DBUS_TYPE_OBJECT_PATH, &chars); return chars; } -bool MessageIter::append_signature (const char *chars) -{ +bool MessageIter::append_signature (const char *chars) { return append_basic (DBUS_TYPE_SIGNATURE, &chars); } -const char *MessageIter::get_signature() -{ +const char *MessageIter::get_signature() { char *chars; get_basic (DBUS_TYPE_SIGNATURE, &chars); return chars; } -MessageIter MessageIter::recurse() -{ +MessageIter MessageIter::recurse() { MessageIter iter (msg()); dbus_message_iter_recurse ( (DBusMessageIter *) &_iter, (DBusMessageIter *) & (iter._iter)); return iter; } -char *MessageIter::signature() const -{ +char *MessageIter::signature() const { return dbus_message_iter_get_signature ( (DBusMessageIter *) &_iter); } -bool MessageIter::append_array (char type, const void *ptr, size_t length) -{ +bool MessageIter::append_array (char type, const void *ptr, size_t length) { return dbus_message_iter_append_fixed_array ( (DBusMessageIter *) &_iter, type, &ptr, length); } -int MessageIter::array_type() -{ +int MessageIter::array_type() { return dbus_message_iter_get_element_type ( (DBusMessageIter *) &_iter); } -int MessageIter::get_array (void *ptr) -{ +int MessageIter::get_array (void *ptr) { int length; dbus_message_iter_get_fixed_array ( (DBusMessageIter *) &_iter, ptr, &length); return length; } -bool MessageIter::is_array() -{ +bool MessageIter::is_array() { return dbus_message_iter_get_arg_type ( (DBusMessageIter *) &_iter) == DBUS_TYPE_ARRAY; } -bool MessageIter::is_dict() -{ +bool MessageIter::is_dict() { return is_array() && dbus_message_iter_get_element_type ( (DBusMessageIter *) _iter) == DBUS_TYPE_DICT_ENTRY; } -MessageIter MessageIter::new_array (const char *sig) -{ +MessageIter MessageIter::new_array (const char *sig) { MessageIter arr (msg()); dbus_message_iter_open_container ( (DBusMessageIter *) &_iter, DBUS_TYPE_ARRAY, sig, (DBusMessageIter *) & (arr._iter) @@ -272,8 +233,7 @@ MessageIter MessageIter::new_array (const char *sig) return arr; } -MessageIter MessageIter::new_variant (const char *sig) -{ +MessageIter MessageIter::new_variant (const char *sig) { MessageIter var (msg()); dbus_message_iter_open_container ( (DBusMessageIter *) _iter, DBUS_TYPE_VARIANT, sig, (DBusMessageIter *) & (var._iter) @@ -281,8 +241,7 @@ MessageIter MessageIter::new_variant (const char *sig) return var; } -MessageIter MessageIter::new_struct() -{ +MessageIter MessageIter::new_struct() { MessageIter stu (msg()); dbus_message_iter_open_container ( (DBusMessageIter *) _iter, DBUS_TYPE_STRUCT, NULL, (DBusMessageIter *) & (stu._iter) @@ -290,8 +249,7 @@ MessageIter MessageIter::new_struct() return stu; } -MessageIter MessageIter::new_dict_entry() -{ +MessageIter MessageIter::new_dict_entry() { MessageIter ent (msg()); dbus_message_iter_open_container ( (DBusMessageIter *) _iter, DBUS_TYPE_DICT_ENTRY, NULL, (DBusMessageIter *) & (ent._iter) @@ -299,13 +257,11 @@ MessageIter MessageIter::new_dict_entry() return ent; } -void MessageIter::close_container (MessageIter &container) -{ +void MessageIter::close_container (MessageIter &container) { dbus_message_iter_close_container ( (DBusMessageIter *) &_iter, (DBusMessageIter *) & (container._iter)); } -static bool is_basic_type (int typecode) -{ +static bool is_basic_type (int typecode) { switch (typecode) { case 'y': @@ -338,8 +294,7 @@ static bool is_basic_type (int typecode) } } -void MessageIter::copy_data (MessageIter &to) -{ +void MessageIter::copy_data (MessageIter &to) { for (MessageIter &from = *this; !from.at_end(); ++from) { if (is_basic_type (from.type())) { debug_log ("copying basic type: %c", from.type()); @@ -373,29 +328,24 @@ void MessageIter::copy_data (MessageIter &to) */ Message::Message() - : _pvt (new Private) -{ + : _pvt (new Private) { } Message::Message (Message::Private *p, bool incref) - : _pvt (p) -{ + : _pvt (p) { if (_pvt->msg && incref) dbus_message_ref (_pvt->msg); } Message::Message (const Message &m) - : _pvt (m._pvt) -{ + : _pvt (m._pvt) { dbus_message_ref (_pvt->msg); } -Message::~Message() -{ +Message::~Message() { dbus_message_unref (_pvt->msg); } -Message &Message::operator = (const Message &m) -{ +Message &Message::operator = (const Message &m) { if (&m != this) { dbus_message_unref (_pvt->msg); _pvt = m._pvt; @@ -405,14 +355,12 @@ Message &Message::operator = (const Message &m) return *this; } -Message Message::copy() -{ +Message Message::copy() { Private *pvt = new Private (dbus_message_copy (_pvt->msg)); return Message (pvt); } -bool Message::append (int first_type, ...) -{ +bool Message::append (int first_type, ...) { va_list vl; va_start (vl, first_type); @@ -422,70 +370,57 @@ bool Message::append (int first_type, ...) return b; } -void Message::terminate() -{ +void Message::terminate() { dbus_message_append_args (_pvt->msg, DBUS_TYPE_INVALID); } -int Message::type() const -{ +int Message::type() const { return dbus_message_get_type (_pvt->msg); } -int Message::serial() const -{ +int Message::serial() const { return dbus_message_get_serial (_pvt->msg); } -int Message::reply_serial() const -{ +int Message::reply_serial() const { return dbus_message_get_reply_serial (_pvt->msg); } -bool Message::reply_serial (int s) -{ +bool Message::reply_serial (int s) { return dbus_message_set_reply_serial (_pvt->msg, s); } -const char *Message::sender() const -{ +const char *Message::sender() const { return dbus_message_get_sender (_pvt->msg); } -bool Message::sender (const char *s) -{ +bool Message::sender (const char *s) { return dbus_message_set_sender (_pvt->msg, s); } -const char *Message::destination() const -{ +const char *Message::destination() const { return dbus_message_get_destination (_pvt->msg); } -bool Message::destination (const char *s) -{ +bool Message::destination (const char *s) { return dbus_message_set_destination (_pvt->msg, s); } -bool Message::is_error() const -{ +bool Message::is_error() const { return type() == DBUS_MESSAGE_TYPE_ERROR; } -bool Message::is_signal (const char *interface, const char *member) const -{ +bool Message::is_signal (const char *interface, const char *member) const { return dbus_message_is_signal (_pvt->msg, interface, member); } -MessageIter Message::writer() -{ +MessageIter Message::writer() { MessageIter iter (*this); dbus_message_iter_init_append (_pvt->msg, (DBusMessageIter *) & (iter._iter)); return iter; } -MessageIter Message::reader() const -{ +MessageIter Message::reader() const { MessageIter iter (const_cast<Message &> (*this)); dbus_message_iter_init (_pvt->msg, (DBusMessageIter *) & (iter._iter)); return iter; @@ -494,52 +429,43 @@ MessageIter Message::reader() const /* */ -ErrorMessage::ErrorMessage() -{ +ErrorMessage::ErrorMessage() { _pvt->msg = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR); } -ErrorMessage::ErrorMessage (const Message &to_reply, const char *name, const char *message) -{ +ErrorMessage::ErrorMessage (const Message &to_reply, const char *name, const char *message) { _pvt->msg = dbus_message_new_error (to_reply._pvt->msg, name, message); } -bool ErrorMessage::operator == (const ErrorMessage &m) const -{ +bool ErrorMessage::operator == (const ErrorMessage &m) const { return dbus_message_is_error (_pvt->msg, m.name()); } -const char *ErrorMessage::name() const -{ +const char *ErrorMessage::name() const { return dbus_message_get_error_name (_pvt->msg); } -bool ErrorMessage::name (const char *n) -{ +bool ErrorMessage::name (const char *n) { return dbus_message_set_error_name (_pvt->msg, n); } /* */ -SignalMessage::SignalMessage (const char *name) -{ +SignalMessage::SignalMessage (const char *name) { _pvt->msg = dbus_message_new (DBUS_MESSAGE_TYPE_SIGNAL); member (name); } -SignalMessage::SignalMessage (const char *path, const char *interface, const char *name) -{ +SignalMessage::SignalMessage (const char *path, const char *interface, const char *name) { _pvt->msg = dbus_message_new_signal (path, interface, name); } -bool SignalMessage::operator == (const SignalMessage &m) const -{ +bool SignalMessage::operator == (const SignalMessage &m) const { return dbus_message_is_signal (_pvt->msg, m.interface(), m.member()); } -const char *SignalMessage::interface() const -{ +const char *SignalMessage::interface() const { return dbus_message_get_interface (_pvt->msg); } @@ -548,53 +474,44 @@ bool SignalMessage::interface (const char *i) return dbus_message_set_interface (_pvt->msg, i); } -const char *SignalMessage::member() const -{ +const char *SignalMessage::member() const { return dbus_message_get_member (_pvt->msg); } -bool SignalMessage::member (const char *m) -{ +bool SignalMessage::member (const char *m) { return dbus_message_set_member (_pvt->msg, m); } -const char *SignalMessage::path() const -{ +const char *SignalMessage::path() const { return dbus_message_get_path (_pvt->msg); } -char ** SignalMessage::path_split() const -{ +char ** SignalMessage::path_split() const { char ** p; dbus_message_get_path_decomposed (_pvt->msg, &p); //todo: return as a std::vector ? return p; } -bool SignalMessage::path (const char *p) -{ +bool SignalMessage::path (const char *p) { return dbus_message_set_path (_pvt->msg, p); } /* */ -CallMessage::CallMessage() -{ +CallMessage::CallMessage() { _pvt->msg = dbus_message_new (DBUS_MESSAGE_TYPE_METHOD_CALL); } -CallMessage::CallMessage (const char *dest, const char *path, const char *iface, const char *method) -{ +CallMessage::CallMessage (const char *dest, const char *path, const char *iface, const char *method) { _pvt->msg = dbus_message_new_method_call (dest, path, iface, method); } -bool CallMessage::operator == (const CallMessage &m) const -{ +bool CallMessage::operator == (const CallMessage &m) const { return dbus_message_is_method_call (_pvt->msg, m.interface(), m.member()); } -const char *CallMessage::interface() const -{ +const char *CallMessage::interface() const { return dbus_message_get_interface (_pvt->msg); } @@ -603,48 +520,40 @@ bool CallMessage::interface (const char *i) return dbus_message_set_interface (_pvt->msg, i); } -const char *CallMessage::member() const -{ +const char *CallMessage::member() const { return dbus_message_get_member (_pvt->msg); } -bool CallMessage::member (const char *m) -{ +bool CallMessage::member (const char *m) { return dbus_message_set_member (_pvt->msg, m); } -const char *CallMessage::path() const -{ +const char *CallMessage::path() const { return dbus_message_get_path (_pvt->msg); } -char ** CallMessage::path_split() const -{ +char ** CallMessage::path_split() const { char ** p; dbus_message_get_path_decomposed (_pvt->msg, &p); return p; } -bool CallMessage::path (const char *p) -{ +bool CallMessage::path (const char *p) { return dbus_message_set_path (_pvt->msg, p); } -const char *CallMessage::signature() const -{ +const char *CallMessage::signature() const { return dbus_message_get_signature (_pvt->msg); } /* */ -ReturnMessage::ReturnMessage (const CallMessage &callee) -{ +ReturnMessage::ReturnMessage (const CallMessage &callee) { _pvt = new Private (dbus_message_new_method_return (callee._pvt->msg)); } -const char *ReturnMessage::signature() const -{ +const char *ReturnMessage::signature() const { return dbus_message_get_signature (_pvt->msg); } diff --git a/sflphone-common/libs/dbus-c++/src/object.cpp b/sflphone-common/libs/dbus-c++/src/object.cpp index 4fa8cd15d11a099afae8a3ccbf52cbe2d0f1da90..a54122fdc8d27ec10cd4a277467bb9ee94688751 100644 --- a/sflphone-common/libs/dbus-c++/src/object.cpp +++ b/sflphone-common/libs/dbus-c++/src/object.cpp @@ -40,12 +40,10 @@ using namespace DBus; Object::Object (Connection &conn, const Path &path, const char *service) - : _conn (conn), _path (path), _service (service ? service : "") -{ + : _conn (conn), _path (path), _service (service ? service : "") { } -Object::~Object() -{ +Object::~Object() { } struct ObjectAdaptor::Private { @@ -59,13 +57,11 @@ static DBusObjectPathVTable _vtable = { NULL, NULL, NULL, NULL }; -void ObjectAdaptor::Private::unregister_function_stub (DBusConnection *conn, void *data) -{ +void ObjectAdaptor::Private::unregister_function_stub (DBusConnection *conn, void *data) { //TODO: what do we have to do here ? } -DBusHandlerResult ObjectAdaptor::Private::message_function_stub (DBusConnection *, DBusMessage *dmsg, void *data) -{ +DBusHandlerResult ObjectAdaptor::Private::message_function_stub (DBusConnection *, DBusMessage *dmsg, void *data) { ObjectAdaptor *o = static_cast<ObjectAdaptor *> (data); if (o) { @@ -89,8 +85,7 @@ DBusHandlerResult ObjectAdaptor::Private::message_function_stub (DBusConnection typedef std::map<Path, ObjectAdaptor *> ObjectAdaptorTable; static ObjectAdaptorTable _adaptor_table; -ObjectAdaptor *ObjectAdaptor::from_path (const Path &path) -{ +ObjectAdaptor *ObjectAdaptor::from_path (const Path &path) { ObjectAdaptorTable::iterator ati = _adaptor_table.find (path); if (ati != _adaptor_table.end()) @@ -99,8 +94,7 @@ ObjectAdaptor *ObjectAdaptor::from_path (const Path &path) return NULL; } -ObjectAdaptorPList ObjectAdaptor::from_path_prefix (const std::string &prefix) -{ +ObjectAdaptorPList ObjectAdaptor::from_path_prefix (const std::string &prefix) { ObjectAdaptorPList ali; ObjectAdaptorTable::iterator ati = _adaptor_table.begin(); @@ -117,8 +111,7 @@ ObjectAdaptorPList ObjectAdaptor::from_path_prefix (const std::string &prefix) return ali; } -ObjectPathList ObjectAdaptor::child_nodes_from_prefix (const std::string &prefix) -{ +ObjectPathList ObjectAdaptor::child_nodes_from_prefix (const std::string &prefix) { ObjectPathList ali; ObjectAdaptorTable::iterator ati = _adaptor_table.begin(); @@ -143,18 +136,15 @@ ObjectPathList ObjectAdaptor::child_nodes_from_prefix (const std::string &prefix } ObjectAdaptor::ObjectAdaptor (Connection &conn, const Path &path) - : Object (conn, path, conn.unique_name()) -{ + : Object (conn, path, conn.unique_name()) { register_obj(); } -ObjectAdaptor::~ObjectAdaptor() -{ +ObjectAdaptor::~ObjectAdaptor() { unregister_obj(); } -void ObjectAdaptor::register_obj() -{ +void ObjectAdaptor::register_obj() { debug_log ("registering local object %s", path().c_str()); if (!dbus_connection_register_object_path (conn()._pvt->conn, path().c_str(), &_vtable, this)) { @@ -164,8 +154,7 @@ void ObjectAdaptor::register_obj() _adaptor_table[path() ] = this; } -void ObjectAdaptor::unregister_obj() -{ +void ObjectAdaptor::unregister_obj() { _adaptor_table.erase (path()); debug_log ("unregistering local object %s", path().c_str()); @@ -173,8 +162,7 @@ void ObjectAdaptor::unregister_obj() dbus_connection_unregister_object_path (conn()._pvt->conn, path().c_str()); } -void ObjectAdaptor::_emit_signal (SignalMessage &sig) -{ +void ObjectAdaptor::_emit_signal (SignalMessage &sig) { sig.path (path().c_str()); conn().send (sig); @@ -184,8 +172,7 @@ struct ReturnLaterError { const Tag *tag; }; -bool ObjectAdaptor::handle_message (const Message &msg) -{ +bool ObjectAdaptor::handle_message (const Message &msg) { switch (msg.type()) { case DBUS_MESSAGE_TYPE_METHOD_CALL: { @@ -221,14 +208,12 @@ bool ObjectAdaptor::handle_message (const Message &msg) } } -void ObjectAdaptor::return_later (const Tag *tag) -{ +void ObjectAdaptor::return_later (const Tag *tag) { ReturnLaterError rle = { tag }; throw rle; } -void ObjectAdaptor::return_now (Continuation *ret) -{ +void ObjectAdaptor::return_now (Continuation *ret) { ret->_conn.send (ret->_return); ContinuationMap::iterator di = _continuations.find (ret->_tag); @@ -238,8 +223,7 @@ void ObjectAdaptor::return_now (Continuation *ret) _continuations.erase (di); } -void ObjectAdaptor::return_error (Continuation *ret, const Error error) -{ +void ObjectAdaptor::return_error (Continuation *ret, const Error error) { ret->_conn.send (ErrorMessage (ret->_call, error.name(), error.message())); ContinuationMap::iterator di = _continuations.find (ret->_tag); @@ -249,16 +233,14 @@ void ObjectAdaptor::return_error (Continuation *ret, const Error error) _continuations.erase (di); } -ObjectAdaptor::Continuation *ObjectAdaptor::find_continuation (const Tag *tag) -{ +ObjectAdaptor::Continuation *ObjectAdaptor::find_continuation (const Tag *tag) { ContinuationMap::iterator di = _continuations.find (tag); return di != _continuations.end() ? di->second : NULL; } ObjectAdaptor::Continuation::Continuation (Connection &conn, const CallMessage &call, const Tag *tag) - : _conn (conn), _call (call), _return (_call), _tag (tag) -{ + : _conn (conn), _call (call), _return (_call), _tag (tag) { _writer = _return.writer(); //todo: verify } @@ -266,18 +248,15 @@ ObjectAdaptor::Continuation::Continuation (Connection &conn, const CallMessage & */ ObjectProxy::ObjectProxy (Connection &conn, const Path &path, const char *service) - : Object (conn, path, service) -{ + : Object (conn, path, service) { register_obj(); } -ObjectProxy::~ObjectProxy() -{ +ObjectProxy::~ObjectProxy() { unregister_obj(); } -void ObjectProxy::register_obj() -{ +void ObjectProxy::register_obj() { debug_log ("registering remote object %s", path().c_str()); _filtered = new Callback<ObjectProxy, bool, const Message &> (this, &ObjectProxy::handle_message); @@ -293,8 +272,7 @@ void ObjectProxy::register_obj() } } -void ObjectProxy::unregister_obj() -{ +void ObjectProxy::unregister_obj() { debug_log ("unregistering remote object %s", path().c_str()); InterfaceProxyTable::const_iterator ii = _interfaces.begin(); @@ -308,8 +286,7 @@ void ObjectProxy::unregister_obj() conn().remove_filter (_filtered); } -Message ObjectProxy::_invoke_method (CallMessage &call) -{ +Message ObjectProxy::_invoke_method (CallMessage &call) { if (call.path() == NULL) call.path (path().c_str()); @@ -319,8 +296,7 @@ Message ObjectProxy::_invoke_method (CallMessage &call) return conn().send_blocking (call); } -bool ObjectProxy::_invoke_method_noreply (CallMessage &call) -{ +bool ObjectProxy::_invoke_method_noreply (CallMessage &call) { if (call.path() == NULL) call.path (path().c_str()); @@ -330,8 +306,7 @@ bool ObjectProxy::_invoke_method_noreply (CallMessage &call) return conn().send (call); } -bool ObjectProxy::handle_message (const Message &msg) -{ +bool ObjectProxy::handle_message (const Message &msg) { switch (msg.type()) { case DBUS_MESSAGE_TYPE_SIGNAL: { diff --git a/sflphone-common/libs/dbus-c++/src/pendingcall.cpp b/sflphone-common/libs/dbus-c++/src/pendingcall.cpp index 775561c21c3a733e99b1f2c0c17c7a7558245936..172e3e6d3932bc50c7a708446bebbb5ee8a1c866 100644 --- a/sflphone-common/libs/dbus-c++/src/pendingcall.cpp +++ b/sflphone-common/libs/dbus-c++/src/pendingcall.cpp @@ -36,22 +36,19 @@ using namespace DBus; PendingCall::Private::Private (DBusPendingCall *dpc) - : call (dpc), dataslot (-1) -{ + : call (dpc), dataslot (-1) { if (!dbus_pending_call_allocate_data_slot (&dataslot)) { throw ErrorNoMemory ("Unable to allocate data slot"); } } -PendingCall::Private::~Private() -{ +PendingCall::Private::~Private() { if (dataslot != -1) { dbus_pending_call_allocate_data_slot (&dataslot); } } -void PendingCall::Private::notify_stub (DBusPendingCall *dpc, void *data) -{ +void PendingCall::Private::notify_stub (DBusPendingCall *dpc, void *data) { PendingCall::Private *pvt = static_cast<PendingCall::Private *> (data); PendingCall pc (pvt); @@ -59,26 +56,22 @@ void PendingCall::Private::notify_stub (DBusPendingCall *dpc, void *data) } PendingCall::PendingCall (PendingCall::Private *p) - : _pvt (p) -{ + : _pvt (p) { if (!dbus_pending_call_set_notify (_pvt->call, Private::notify_stub, p, NULL)) { throw ErrorNoMemory ("Unable to initialize pending call"); } } PendingCall::PendingCall (const PendingCall &c) - : _pvt (c._pvt) -{ + : _pvt (c._pvt) { dbus_pending_call_ref (_pvt->call); } -PendingCall::~PendingCall() -{ +PendingCall::~PendingCall() { dbus_pending_call_unref (_pvt->call); } -PendingCall &PendingCall::operator = (const PendingCall &c) -{ +PendingCall &PendingCall::operator = (const PendingCall &c) { if (&c != this) { dbus_pending_call_unref (_pvt->call); _pvt = c._pvt; @@ -88,40 +81,33 @@ PendingCall &PendingCall::operator = (const PendingCall &c) return *this; } -bool PendingCall::completed() -{ +bool PendingCall::completed() { return dbus_pending_call_get_completed (_pvt->call); } -void PendingCall::cancel() -{ +void PendingCall::cancel() { dbus_pending_call_cancel (_pvt->call); } -void PendingCall::block() -{ +void PendingCall::block() { dbus_pending_call_block (_pvt->call); } -void PendingCall::data (void *p) -{ +void PendingCall::data (void *p) { if (!dbus_pending_call_set_data (_pvt->call, _pvt->dataslot, p, NULL)) { throw ErrorNoMemory ("Unable to initialize data slot"); } } -void *PendingCall::data() -{ +void *PendingCall::data() { return dbus_pending_call_get_data (_pvt->call, _pvt->dataslot); } -Slot<void, PendingCall &>& PendingCall::slot() -{ +Slot<void, PendingCall &>& PendingCall::slot() { return _pvt->slot; } -Message PendingCall::steal_reply() -{ +Message PendingCall::steal_reply() { DBusMessage *dmsg = dbus_pending_call_steal_reply (_pvt->call); if (!dmsg) { diff --git a/sflphone-common/libs/dbus-c++/src/property.cpp b/sflphone-common/libs/dbus-c++/src/property.cpp index e8b02fdaded719b0b8d9e763e0dc42e7e9f8b42c..0afccd9b4cc7e9e3c311ae35f803e98eda540fe0 100644 --- a/sflphone-common/libs/dbus-c++/src/property.cpp +++ b/sflphone-common/libs/dbus-c++/src/property.cpp @@ -35,14 +35,12 @@ using namespace DBus; static const char *properties_name = "org.freedesktop.DBus.Properties"; PropertiesAdaptor::PropertiesAdaptor() - : InterfaceAdaptor (properties_name) -{ + : InterfaceAdaptor (properties_name) { register_method (PropertiesAdaptor, Get, Get); register_method (PropertiesAdaptor, Set, Set); } -Message PropertiesAdaptor::Get (const CallMessage &call) -{ +Message PropertiesAdaptor::Get (const CallMessage &call) { MessageIter ri = call.reader(); std::string iface_name; @@ -73,8 +71,7 @@ Message PropertiesAdaptor::Get (const CallMessage &call) return reply; } -Message PropertiesAdaptor::Set (const CallMessage &call) -{ +Message PropertiesAdaptor::Set (const CallMessage &call) { MessageIter ri = call.reader(); std::string iface_name; @@ -97,8 +94,7 @@ Message PropertiesAdaptor::Set (const CallMessage &call) return reply; } -IntrospectedInterface *const PropertiesAdaptor::introspect() const -{ +IntrospectedInterface *const PropertiesAdaptor::introspect() const { static IntrospectedArgument Get_args[] = { { "interface_name", "s", true }, { "property_name", "s", true }, @@ -132,19 +128,16 @@ IntrospectedInterface *const PropertiesAdaptor::introspect() const } PropertiesProxy::PropertiesProxy() - : InterfaceProxy (properties_name) -{ + : InterfaceProxy (properties_name) { } -Variant PropertiesProxy::Get (const std::string &iface, const std::string &property) -{ +Variant PropertiesProxy::Get (const std::string &iface, const std::string &property) { //todo Variant v; return v; } -void PropertiesProxy::Set (const std::string &iface, const std::string &property, const Variant &value) -{ +void PropertiesProxy::Set (const std::string &iface, const std::string &property, const Variant &value) { //todo } diff --git a/sflphone-common/libs/dbus-c++/src/server.cpp b/sflphone-common/libs/dbus-c++/src/server.cpp index b3dbfe267b96254e70a3bc9dee77f48bb66dc97d..f2bc5d293870c4e092ed7073fb21ce7954307b44 100644 --- a/sflphone-common/libs/dbus-c++/src/server.cpp +++ b/sflphone-common/libs/dbus-c++/src/server.cpp @@ -36,16 +36,13 @@ using namespace DBus; Server::Private::Private (DBusServer *s) - : server (s) -{ + : server (s) { } -Server::Private::~Private() -{ +Server::Private::~Private() { } -void Server::Private::on_new_conn_cb (DBusServer *server, DBusConnection *conn, void *data) -{ +void Server::Private::on_new_conn_cb (DBusServer *server, DBusConnection *conn, void *data) { Server *s = static_cast<Server *> (data); Connection nc (new Connection::Private (conn, s->_pvt.get())); @@ -57,8 +54,7 @@ void Server::Private::on_new_conn_cb (DBusServer *server, DBusConnection *conn, debug_log ("incoming connection 0x%08x", conn); } -Server::Server (const char *address) -{ +Server::Server (const char *address) { InternalError e; DBusServer *server = dbus_server_listen (address, e); @@ -80,13 +76,11 @@ Server::Server(const Server &s) dbus_server_ref(_pvt->server); } */ -Server::~Server() -{ +Server::~Server() { dbus_server_unref (_pvt->server); } -Dispatcher *Server::setup (Dispatcher *dispatcher) -{ +Dispatcher *Server::setup (Dispatcher *dispatcher) { debug_log ("registering stubs for server %p", _pvt->server); Dispatcher *prev = _pvt->dispatcher; @@ -114,18 +108,15 @@ Dispatcher *Server::setup (Dispatcher *dispatcher) return prev; } -bool Server::operator == (const Server &s) const -{ +bool Server::operator == (const Server &s) const { return _pvt->server == s._pvt->server; } -bool Server::listening() const -{ +bool Server::listening() const { return dbus_server_get_is_connected (_pvt->server); } -void Server::disconnect() -{ +void Server::disconnect() { dbus_server_disconnect (_pvt->server); } diff --git a/sflphone-common/libs/dbus-c++/src/types.cpp b/sflphone-common/libs/dbus-c++/src/types.cpp index e38d01cdb4740f72796e6c61144be7ab3e2094af..9e16bde4bd4c07c2bb3ee05ac9e332241b9fd2ce 100644 --- a/sflphone-common/libs/dbus-c++/src/types.cpp +++ b/sflphone-common/libs/dbus-c++/src/types.cpp @@ -37,20 +37,17 @@ using namespace DBus; Variant::Variant() - : _msg (CallMessage()) // dummy message used as temporary storage for variant data -{ + : _msg (CallMessage()) { // dummy message used as temporary storage for variant data } Variant::Variant (MessageIter &it) - : _msg (CallMessage()) -{ + : _msg (CallMessage()) { MessageIter vi = it.recurse(); MessageIter mi = _msg.writer(); vi.copy_data (mi); } -Variant &Variant::operator = (const Variant &v) -{ +Variant &Variant::operator = (const Variant &v) { if (&v != this) { _msg = v._msg; } @@ -58,14 +55,12 @@ Variant &Variant::operator = (const Variant &v) return *this; } -void Variant::clear() -{ +void Variant::clear() { CallMessage empty; _msg = empty; } -const Signature Variant::signature() const -{ +const Signature Variant::signature() const { char *sigbuf = reader().signature(); Signature signature = sigbuf; @@ -75,8 +70,7 @@ const Signature Variant::signature() const return signature; } -MessageIter &operator << (MessageIter &iter, const Variant &val) -{ +MessageIter &operator << (MessageIter &iter, const Variant &val) { const Signature sig = val.signature(); MessageIter rit = val.reader(); @@ -89,8 +83,7 @@ MessageIter &operator << (MessageIter &iter, const Variant &val) return iter; } -MessageIter &operator >> (MessageIter &iter, Variant &val) -{ +MessageIter &operator >> (MessageIter &iter, Variant &val) { if (iter.type() != DBUS_TYPE_VARIANT) throw ErrorInvalidArgs ("variant type expected"); diff --git a/sflphone-common/libs/dbus-c++/tools/generate_adaptor.cpp b/sflphone-common/libs/dbus-c++/tools/generate_adaptor.cpp index c8f0cd6abb4d08c3951e6ff8da50c80a005c4e70..98721703facb188a635bac1ddadea8e415a0e74a 100644 --- a/sflphone-common/libs/dbus-c++/tools/generate_adaptor.cpp +++ b/sflphone-common/libs/dbus-c++/tools/generate_adaptor.cpp @@ -39,8 +39,7 @@ extern const char *dbus_includes; /*! Generate adaptor code for a XML introspection */ -void generate_adaptor (Xml::Document &doc, const char *filename) -{ +void generate_adaptor (Xml::Document &doc, const char *filename) { ostringstream body; ostringstream head; vector <string> include_vector; diff --git a/sflphone-common/libs/dbus-c++/tools/generate_proxy.cpp b/sflphone-common/libs/dbus-c++/tools/generate_proxy.cpp index 288dfa4845ec403439fced710c63a3a56747dbca..95987f45c7a308d682cf43ef5fba2ae263b53bc3 100644 --- a/sflphone-common/libs/dbus-c++/tools/generate_proxy.cpp +++ b/sflphone-common/libs/dbus-c++/tools/generate_proxy.cpp @@ -39,8 +39,7 @@ extern const char *dbus_includes; /*! Generate proxy code for a XML introspection */ -void generate_proxy (Xml::Document &doc, const char *filename) -{ +void generate_proxy (Xml::Document &doc, const char *filename) { ostringstream body; ostringstream head; vector <string> include_vector; diff --git a/sflphone-common/libs/dbus-c++/tools/generator_utils.cpp b/sflphone-common/libs/dbus-c++/tools/generator_utils.cpp index 9b5a364966a7631eeea48a7c2b421bd7737082e9..3549632ece299ee4f496d1a4bc53bb3b0c8d4cf3 100644 --- a/sflphone-common/libs/dbus-c++/tools/generator_utils.cpp +++ b/sflphone-common/libs/dbus-c++/tools/generator_utils.cpp @@ -42,22 +42,19 @@ const char *dbus_includes = "\n\ #include <cassert>\n\ "; - void underscorize (string &str) - { + void underscorize (string &str) { for (unsigned int i = 0; i < str.length(); ++i) { if (!isalpha (str[i]) && !isdigit (str[i])) str[i] = '_'; } } - string stub_name (string name) - { + string stub_name (string name) { underscorize (name); return "_" + name + "_stub"; } - const char *atomic_type_to_string (char t) - { + const char *atomic_type_to_string (char t) { static struct { char type; @@ -88,8 +85,7 @@ const char *dbus_includes = "\n\ return atos[i].name; } - void _parse_signature (const string &signature, string &type, unsigned int &i) - { + void _parse_signature (const string &signature, string &type, unsigned int &i) { for (; i < signature.length(); ++i) { switch (signature[i]) { @@ -164,8 +160,7 @@ const char *dbus_includes = "\n\ } } - string signature_to_type (const string &signature) - { + string signature_to_type (const string &signature) { string type; unsigned int i = 0; _parse_signature (signature, type, i); diff --git a/sflphone-common/libs/dbus-c++/tools/introspect.cpp b/sflphone-common/libs/dbus-c++/tools/introspect.cpp index 88a767396139d976588c1d26464cceaa9153c6bb..7459007d548c921cf8c84d5c1374634d5645e115 100644 --- a/sflphone-common/libs/dbus-c++/tools/introspect.cpp +++ b/sflphone-common/libs/dbus-c++/tools/introspect.cpp @@ -32,8 +32,7 @@ static bool systembus; static char *path; static char *service; -void niam (int sig) -{ +void niam (int sig) { DBus::Connection conn = systembus ? DBus::Connection::SystemBus() : DBus::Connection::SessionBus(); IntrospectedObject io (conn, path, service); @@ -43,8 +42,7 @@ void niam (int sig) dispatcher.leave(); } -int main (int argc, char ** argv) -{ +int main (int argc, char ** argv) { signal (SIGTERM, niam); signal (SIGINT, niam); signal (SIGALRM, niam); diff --git a/sflphone-common/libs/dbus-c++/tools/xml.cpp b/sflphone-common/libs/dbus-c++/tools/xml.cpp index 2ba8635a3c9508d2f73e5cdeda87f84d7ed0b76c..0393f587ca85d0cf41bdf25071ba4c646172a636 100644 --- a/sflphone-common/libs/dbus-c++/tools/xml.cpp +++ b/sflphone-common/libs/dbus-c++/tools/xml.cpp @@ -28,8 +28,7 @@ #include <expat.h> -std::istream &operator >> (std::istream &in, DBus::Xml::Document &doc) -{ +std::istream &operator >> (std::istream &in, DBus::Xml::Document &doc) { std::stringbuf xmlbuf; in.get (xmlbuf, '\0'); doc.from_xml (xmlbuf.str()); @@ -37,8 +36,7 @@ std::istream &operator >> (std::istream &in, DBus::Xml::Document &doc) return in; } -std::ostream &operator << (std::ostream &out, const DBus::Xml::Document &doc) -{ +std::ostream &operator << (std::ostream &out, const DBus::Xml::Document &doc) { return out << doc.to_xml(); } @@ -46,8 +44,7 @@ using namespace DBus; using namespace DBus::Xml; -Error::Error (const char *error, int line, int column) -{ +Error::Error (const char *error, int line, int column) { std::ostringstream estream; estream << "line " << line << ", column " << column << ": " << error; @@ -56,8 +53,7 @@ Error::Error (const char *error, int line, int column) } Node::Node (const char *n, const char ** a) - : name (n) -{ + : name (n) { if (a) for (int i = 0; a[i]; i += 2) { _attrs[a[i]] = a[i+1]; @@ -66,8 +62,7 @@ Node::Node (const char *n, const char ** a) } } -Nodes Nodes::operator[] (const std::string &key) -{ +Nodes Nodes::operator[] (const std::string &key) { Nodes result; for (iterator i = begin(); i != end(); ++i) { @@ -79,8 +74,7 @@ Nodes Nodes::operator[] (const std::string &key) return result; } -Nodes Nodes::select (const std::string &attr, const std::string &value) -{ +Nodes Nodes::select (const std::string &attr, const std::string &value) { Nodes result; for (iterator i = begin(); i != end(); ++i) { @@ -91,8 +85,7 @@ Nodes Nodes::select (const std::string &attr, const std::string &value) return result; } -Nodes Node::operator[] (const std::string &key) -{ +Nodes Node::operator[] (const std::string &key) { Nodes result; if (key.length() == 0) return result; @@ -105,24 +98,21 @@ Nodes Node::operator[] (const std::string &key) return result; } -std::string Node::get (const std::string &attribute) -{ +std::string Node::get (const std::string &attribute) { if (_attrs.find (attribute) != _attrs.end()) return _attrs[attribute]; else return ""; } -void Node::set (const std::string &attribute, std::string value) -{ +void Node::set (const std::string &attribute, std::string value) { if (value.length()) _attrs[attribute] = value; else _attrs.erase (value); } -std::string Node::to_xml() const -{ +std::string Node::to_xml() const { std::string xml; int depth = 0; @@ -131,8 +121,7 @@ std::string Node::to_xml() const return xml; } -void Node::_raw_xml (std::string &xml, int &depth) const -{ +void Node::_raw_xml (std::string &xml, int &depth) const { xml.append (depth *2, ' '); xml.append ("<"+name); @@ -167,18 +156,15 @@ void Node::_raw_xml (std::string &xml, int &depth) const } Document::Document() - : root (0), _depth (0) -{ + : root (0), _depth (0) { } Document::Document (const std::string &xml) - : root (0), _depth (0) -{ + : root (0), _depth (0) { from_xml (xml); } -Document::~Document() -{ +Document::~Document() { delete root; } @@ -192,8 +178,7 @@ struct Document::Expat { static void end_element_handler (void *data, const XML_Char *name); }; -void Document::from_xml (const std::string &xml) -{ +void Document::from_xml (const std::string &xml) { _depth = 0; delete root; root = 0; @@ -234,23 +219,19 @@ void Document::from_xml (const std::string &xml) } } -std::string Document::to_xml() const -{ +std::string Document::to_xml() const { return root->to_xml(); } void Document::Expat::start_doctype_decl_handler ( void *data, const XML_Char *name, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset -) -{ +) { } -void Document::Expat::end_doctype_decl_handler (void *data) -{ +void Document::Expat::end_doctype_decl_handler (void *data) { } -void Document::Expat::start_element_handler (void *data, const XML_Char *name, const XML_Char **atts) -{ +void Document::Expat::start_element_handler (void *data, const XML_Char *name, const XML_Char **atts) { Document *doc = (Document *) data; //debug_log("xml:%d -> %s", doc->_depth, name); @@ -272,8 +253,7 @@ void Document::Expat::start_element_handler (void *data, const XML_Char *name, c doc->_depth++; } -void Document::Expat::character_data_handler (void *data, const XML_Char *chars, int len) -{ +void Document::Expat::character_data_handler (void *data, const XML_Char *chars, int len) { Document *doc = (Document *) data; Node *nod = doc->root; @@ -294,8 +274,7 @@ void Document::Expat::character_data_handler (void *data, const XML_Char *chars, nod->cdata = std::string (chars, x, y+1); } -void Document::Expat::end_element_handler (void *data, const XML_Char *name) -{ +void Document::Expat::end_element_handler (void *data, const XML_Char *name) { Document *doc = (Document *) data; //debug_log("xml:%d <- %s", doc->_depth, name); diff --git a/sflphone-common/libs/dbus-c++/tools/xml2cpp.cpp b/sflphone-common/libs/dbus-c++/tools/xml2cpp.cpp index ecc249c67fb9a052e499b4a8e52c73176242e256..300a21d6cdc17e0ed1bec4467256d8c831abc198 100644 --- a/sflphone-common/libs/dbus-c++/tools/xml2cpp.cpp +++ b/sflphone-common/libs/dbus-c++/tools/xml2cpp.cpp @@ -42,8 +42,7 @@ using namespace DBus; //typedef map<string,string> TypeCache; -void usage (const char *argv0) -{ +void usage (const char *argv0) { cerr << endl << "Usage: " << argv0 << " <xmlfile> [ --proxy=<outfile.h> ] [ --adaptor=<outfile.h> ]" << endl << endl; exit (-1); @@ -62,8 +61,7 @@ bool is_atomic_type(const string &type) return type.length() == 1 && char_to_atomic_type(type[0]) != DBUS_TYPE_INVALID; }*/ -int main (int argc, char ** argv) -{ +int main (int argc, char ** argv) { if (argc < 2) { usage (argv[0]); } diff --git a/sflphone-common/libs/pjproject/autogen.sh b/sflphone-common/libs/pjproject/autogen.sh index 695c27e85ee6a3fd11a52bae54b04f11ab6579b7..ccbfb98375458fbb561510487fa65905c7a09915 100755 --- a/sflphone-common/libs/pjproject/autogen.sh +++ b/sflphone-common/libs/pjproject/autogen.sh @@ -18,6 +18,14 @@ elif [ -e /usr/lib/rpm/config.guess ]; then rm -f config.sub config.guess ln -s /usr/lib/rpm/config.sub . ln -s /usr/lib/rpm/config.guess . +elif [ -e /usr/share/automake-*/config.guess ]; then + rm -f config.sub config.guess + ln -s /usr/share/automake-*/config.sub . + ln -s /usr/share/automake-*/config.guess . +elif [ -e /usr/share/libtool/config/config.guess ]; then + rm -f config.sub config.guess + ln -s /usr/share/libtool/config/config.sub . + ln -s /usr/share/libtool/config/config.guess . else aclocal --force automake --add-missing --force-missing --copy diff --git a/sflphone-common/libs/pjproject/pjlib/src/pjlib-test/udp_echo_srv_ioqueue.c b/sflphone-common/libs/pjproject/pjlib/src/pjlib-test/udp_echo_srv_ioqueue.c index 1428e1b282c4663e6363e7c09537e7b2888ea42d..6bf91de888985f2ab1d7c553b6aa62ff258aefdd 100644 --- a/sflphone-common/libs/pjproject/pjlib/src/pjlib-test/udp_echo_srv_ioqueue.c +++ b/sflphone-common/libs/pjproject/pjlib/src/pjlib-test/udp_echo_srv_ioqueue.c @@ -162,6 +162,8 @@ static int worker_thread(void *arg) rc = pj_ioqueue_poll(ioqueue, &timeout); } PJ_UNREACHED(return 0;) + + return 0; } int udp_echo_srv_ioqueue(void) diff --git a/sflphone-common/libs/pjproject/pjlib/src/pjlib-test/udp_echo_srv_sync.c b/sflphone-common/libs/pjproject/pjlib/src/pjlib-test/udp_echo_srv_sync.c index ceff924389d7fa0e96f2397c46fbf07162bc6420..9b5aec652de68a18bbaf616d3d2aa66368b827b2 100644 --- a/sflphone-common/libs/pjproject/pjlib/src/pjlib-test/udp_echo_srv_sync.c +++ b/sflphone-common/libs/pjproject/pjlib/src/pjlib-test/udp_echo_srv_sync.c @@ -68,6 +68,8 @@ static int worker_thread(void *arg) } } PJ_UNREACHED(return 0;) + + return 0; } diff --git a/sflphone-common/libs/utilspp/singleton/LifetimeLibrary.cpp b/sflphone-common/libs/utilspp/singleton/LifetimeLibrary.cpp index 6722e91c301921ffbe73d6d48cc5015d43bcc9db..6e71baddaad90bc1922457fcae4791c3b53cea3d 100644 --- a/sflphone-common/libs/utilspp/singleton/LifetimeLibrary.cpp +++ b/sflphone-common/libs/utilspp/singleton/LifetimeLibrary.cpp @@ -6,14 +6,12 @@ utilspp::LifetimeLibraryImpl::LifetimeLibraryImpl() mTrackerArray (NULL), mNbElements (0) {} -utilspp::LifetimeLibraryImpl::~LifetimeLibraryImpl() -{ +utilspp::LifetimeLibraryImpl::~LifetimeLibraryImpl() { terminate(); } void -utilspp::LifetimeLibraryImpl::add (utilspp::PrivateMembers::LifetimeTracker *tracker) -{ +utilspp::LifetimeLibraryImpl::add (utilspp::PrivateMembers::LifetimeTracker *tracker) { utilspp::PrivateMembers::TrackerArray newArray = static_cast< utilspp::PrivateMembers::TrackerArray > (std::realloc (mTrackerArray, mNbElements + 1)); @@ -38,8 +36,7 @@ utilspp::LifetimeLibraryImpl::add (utilspp::PrivateMembers::LifetimeTracker *tra }; void -utilspp::LifetimeLibraryImpl::terminate() -{ +utilspp::LifetimeLibraryImpl::terminate() { //The number of elements MUST always be equal or over zero. assert (mNbElements >= 0); @@ -63,8 +60,7 @@ utilspp::LifetimeLibraryImpl::terminate() } unsigned int -utilspp::getLongevity (utilspp::LifetimeLibraryImpl *) -{ +utilspp::getLongevity (utilspp::LifetimeLibraryImpl *) { return 0; } diff --git a/sflphone-common/libs/utilspp/singleton/PrivateMembers.cpp b/sflphone-common/libs/utilspp/singleton/PrivateMembers.cpp index 004517f494fd3e42447bd7a2530ec98c431651ce..a033e0c54c6255fca5144b7963c50ea2ace9ab07 100644 --- a/sflphone-common/libs/utilspp/singleton/PrivateMembers.cpp +++ b/sflphone-common/libs/utilspp/singleton/PrivateMembers.cpp @@ -18,14 +18,12 @@ bool utilspp::PrivateMembers::LifetimeTracker::compare ( const LifetimeTracker *l, const LifetimeTracker *r -) -{ +) { return l->mLongevity < r->mLongevity; } void -utilspp::PrivateMembers::atExitFunc() -{ +utilspp::PrivateMembers::atExitFunc() { assert ( (mTrackerArray != NULL) && (mNbElements > 0)); diff --git a/sflphone-common/src/Makefile.am b/sflphone-common/src/Makefile.am index 10950a290304ca4bfb9a69a28ae31562e9b453eb..fff35078332d02e3e7d3abe45747ec52f11dee66 100644 --- a/sflphone-common/src/Makefile.am +++ b/sflphone-common/src/Makefile.am @@ -10,6 +10,7 @@ sflphoned_SOURCES = \ conference.cpp \ voiplink.cpp \ main.cpp \ + preferences.cpp \ managerimpl.cpp \ managerimpl_registration.cpp \ observer.cpp \ @@ -47,6 +48,7 @@ noinst_LTLIBRARIES = libsflphone.la noinst_HEADERS = \ conference.h \ voiplink.h \ + preferences.h \ managerimpl.h \ manager.h \ global.h \ @@ -82,7 +84,8 @@ libsflphone_la_LDFLAGS = \ @PULSEAUDIO_LIBS@ \ @SAMPLERATE_LIBS@ \ @libssl_LIBS@ \ - @UUID_LIBS@ + @UUID_LIBS@ \ + @yaml_LIBS@ libsflphone_la_CFLAGS = \ @CCGNU2_CFLAGS@ \ @@ -94,13 +97,9 @@ libsflphone_la_CFLAGS = \ @PULSEAUDIO_CFLAGS@ \ @SAMPLERATE_CFLAGS@ \ @libssl_CFLAGS@ \ - @UUID_CFLAGS@ + @UUID_CFLAGS@ \ + @yaml_CFLAGS@ libsflphone_la_SOURCES = -indent: - @echo "Indenting code:" - if [ -f $(ASTYLERC) ] ; then \ - $(indent) --options=$(ASTYLERC) --recursive *.cpp *.h; \ - fi - +all: indent diff --git a/sflphone-common/src/account.cpp b/sflphone-common/src/account.cpp index 199cd61e471dd49f917f174f523bb6e48d9f6577..6b369c10d5ce6e7320af4ba56ee81ac4ff649423 100644 --- a/sflphone-common/src/account.cpp +++ b/sflphone-common/src/account.cpp @@ -36,9 +36,14 @@ Account::Account (const AccountID& accountID, std::string type) : _accountID (accountID) , _link (NULL) - , _enabled (false) + , _enabled (true) , _type (type) , _codecOrder () + , _codecStr ("") + , _ringtonePath ("/usr/share/sflphone/ringtones/konga.ul") + , _ringtoneEnabled (true) + , _displayName ("") + , _useragent ("SFLphone") { setRegistrationState (Unregistered); } @@ -50,17 +55,11 @@ Account::~Account() void Account::loadConfig() { - std::string p; + // If IAX is not supported, do not register this account +#ifndef USE_IAX - p = Manager::instance().getConfigString (_accountID , CONFIG_ACCOUNT_TYPE); -#ifdef USE_IAX - _enabled = (Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_ENABLE) == "true") ? true : false; -#else - - if (p == "IAX") + if (_type == "IAX") _enabled = false; - else - _enabled = (Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_ENABLE) == "true") ? true : false; #endif @@ -83,17 +82,16 @@ void Account::loadAudioCodecs (void) { // if the user never set the codec list, use the default configuration for this account - if (Manager::instance ().getConfigString (_accountID, "ActiveCodecs") == "") { + if (_codecStr == "") { _info ("Account: use the default order"); Manager::instance ().getCodecDescriptorMap ().setDefaultOrder(); } - // else retrieve the one set in the user config file else { std::vector<std::string> active_list = Manager::instance ().retrieveActiveCodecs(); // This property is now set per account basis - std::string s = Manager::instance ().getConfigString (_accountID, "ActiveCodecs"); - setActiveCodecs (Manager::instance ().unserialize (s)); + // std::string s = Manager::instance ().getConfigString (_accountID, "ActiveCodecs"); + setActiveCodecs (Manager::instance ().unserialize (_codecStr)); } } @@ -117,10 +115,6 @@ void Account::setActiveCodecs (const std::vector <std::string> &list) } // setConfig - std::string s = Manager::instance ().serialize (list); - - // Set the config per account - Manager::instance().setConfig (_accountID, "ActiveCodecs", s); - + _codecStr = Manager::instance ().serialize (list); } diff --git a/sflphone-common/src/account.h b/sflphone-common/src/account.h index 80bfbd36ba1838b9e0c2d6dc482b3185f3e44219..fd75f67a67abf365aab9046bd59ab8ee44ae192c 100644 --- a/sflphone-common/src/account.h +++ b/sflphone-common/src/account.h @@ -2,17 +2,17 @@ * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> * Author: Yan Morin <yan.morin@savoirfairelinux.com> - * + * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -37,6 +37,7 @@ #include "config/config.h" #include "voiplink.h" +#include "config/serializable.h" class VoIPLink; @@ -51,25 +52,25 @@ typedef std::string AccountID; /** Contains all the state an Voip can be in */ typedef enum RegistrationState { - Unregistered, - Trying, - Registered, - Error, - ErrorAuth , - ErrorNetwork , - ErrorHost, - ErrorExistStun, - ErrorConfStun, - NumberOfState + Unregistered, + Trying, + Registered, + Error, + ErrorAuth , + ErrorNetwork , + ErrorHost, + ErrorExistStun, + ErrorConfStun, + NumberOfState } RegistrationState; #define AccountNULL "" -// Account identifier +// Account identifier #define ACCOUNT_ID "Account.id" // Common account parameters -#define CONFIG_ACCOUNT_TYPE "Account.type" +#define CONFIG_ACCOUNT_TYPE "Account.type" #define CONFIG_ACCOUNT_ALIAS "Account.alias" #define CONFIG_ACCOUNT_MAILBOX "Account.mailbox" #define CONFIG_ACCOUNT_ENABLE "Account.enable" @@ -77,6 +78,8 @@ typedef enum RegistrationState { #define CONFIG_ACCOUNT_REGISTRATION_EXPIRE "Account.expire" #define CONFIG_CREDENTIAL_NUMBER "Credential.count" #define ACCOUNT_DTMF_TYPE "Account.dtmfType" +#define CONFIG_RINGTONE_PATH "Account.ringtonePath" +#define CONFIG_RINGTONE_ENABLED "Account.ringtoneEnabled" #define HOSTNAME "hostname" #define USERNAME "username" @@ -122,26 +125,53 @@ typedef enum RegistrationState { #define TLS_SERVER_NAME "TLS.serverName" #define TLS_VERIFY_SERVER "TLS.verifyServer" #define TLS_VERIFY_CLIENT "TLS.verifyClient" -#define TLS_REQUIRE_CLIENT_CERTIFICATE "TLS.requireClientCertificate" +#define TLS_REQUIRE_CLIENT_CERTIFICATE "TLS.requireClientCertificate" #define TLS_NEGOTIATION_TIMEOUT_SEC "TLS.negotiationTimeoutSec" #define TLS_NEGOTIATION_TIMEOUT_MSEC "TLS.negotiationTimemoutMsec" #define REGISTRATION_STATUS "Status" -#define REGISTRATION_STATE_CODE "Registration.code" +#define REGISTRATION_STATE_CODE "Registration.code" #define REGISTRATION_STATE_DESCRIPTION "Registration.description" -class Account{ +// General configuration keys for accounts +const Conf::Key aliasKey ("alias"); +const Conf::Key typeKey ("type"); +const Conf::Key idKey ("id"); +const Conf::Key usernameKey ("username"); +const Conf::Key passwordKey ("password"); +const Conf::Key hostnameKey ("hostname"); +const Conf::Key accountEnableKey ("enable"); +const Conf::Key mailboxKey ("mailbox"); + +const Conf::Key codecsKey ("codecs"); // 0/9/110/111/112/ +const Conf::Key ringtonePathKey ("ringtonePath"); +const Conf::Key ringtoneEnabledKey ("ringtoneEnabled"); +const Conf::Key displayNameKey ("displayName"); + +#define find_in_map(X, Y) if((iter = map_cpy.find(X)) != map_cpy.end()) { Y = iter->second; } + +class Account : public Serializable +{ public: - Account(const AccountID& accountID, std::string type); + Account (const AccountID& accountID, std::string type); /** * Virtual destructor */ virtual ~Account(); + virtual void serialize (Conf::YamlEmitter *emitter) = 0; + + virtual void unserialize (Conf::MappingNode *map) = 0; + + virtual void setAccountDetails (const std::map<std::string, std::string>& details) = 0; + + virtual std::map<std::string, std::string> getAccountDetails() = 0; + + /** * Load the settings for this account. */ @@ -151,13 +181,17 @@ class Account{ * Get the account ID * @return constant account id */ - inline const AccountID& getAccountID() { return _accountID; } + inline const AccountID& getAccountID() { + return _accountID; + } /** * Get the voiplink pointer * @return VoIPLink* the pointer or 0 */ - inline VoIPLink* getVoIPLink() { return _link; } + inline VoIPLink* getVoIPLink() { + return _link; + } virtual void setVoIPLink () = 0; @@ -174,76 +208,137 @@ class Account{ virtual int unregisterVoIPLink() = 0; /** - * Tell if the account is enable or not. + * Tell if the account is enable or not. * @return true if enabled * false otherwise */ - bool isEnabled() { return _enabled; } + bool isEnabled() { + return _enabled; + } + + void setEnabled (bool enabl) { + _enabled = enabl; + } /** * Get the registration state of the specified link * @return RegistrationState The registration state of underlying VoIPLink */ - inline RegistrationState getRegistrationState() { return _registrationState; } + inline RegistrationState getRegistrationState() { + return _registrationState; + } /** * Set the registration state of the specified link * @param state The registration state of underlying VoIPLink */ - void setRegistrationState( RegistrationState state ); - + void setRegistrationState (RegistrationState state); + /** * Set the latest up-to-date state code - * for that account. These codes are + * for that account. These codes are * those used in SIP and IAX (eg. 200, 500 ...) * @param state The Code:Description state * @return void */ - void setRegistrationStateDetailed(std::pair<int, std::string> state) { _registrationStateDetailed = state; } - + void setRegistrationStateDetailed (std::pair<int, std::string> state) { + _registrationStateDetailed = state; + } + /** * Get the latest up-to-date state code - * for that account. These codes are + * for that account. These codes are * those used in SIP and IAX (eg. 200, 500 ...) * @param void * @return std::pair<int, std::string> A Code:Description state */ - std::pair<int, std::string> getRegistrationStateDetailed(void) { return _registrationStateDetailed; } - + std::pair<int, std::string> getRegistrationStateDetailed (void) { + return _registrationStateDetailed; + } + /* inline functions */ /* They should be treated like macro definitions by the C++ compiler */ - inline std::string getUsername( void ) { return _username; } - inline void setUsername( std::string username) { _username = username; } + inline std::string getUsername (void) { + return _username; + } + inline void setUsername (std::string username) { + _username = username; + } + + inline std::string getHostname (void) { + return _hostname; + } + inline void setHostname (std::string hostname) { + _hostname = hostname; + } + + inline std::string getPassword (void) { + return _password; + } + inline void setPassword (std::string password) { + _password = password; + } + + inline std::string getAlias (void) { + return _alias; + } + inline void setAlias (std::string alias) { + _alias = alias; + } + + inline std::string getType (void) { + return _type; + } + inline void setType (std::string type) { + _type = type; + } - inline std::string getHostname( void ) { return _hostname; } - inline void setHostname( std::string hostname) { _hostname = hostname; } - - inline std::string getPassword( void ) { return _password; } - inline void setPassword( std::string password ) { _password = password; } - - inline std::string getAlias( void ) { return _alias; } - inline void setAlias( std::string alias ) { _alias = alias; } - - inline std::string getType( void ) { return _type; } - inline void setType( std::string type ) { _type = type; } - - /** - * Accessor to data structures - * @return CodecOrder& The list that reflects the user's choice - */ - inline CodecOrder& getActiveCodecs() { return _codecOrder; } - - void setActiveCodecs (const std::vector <std::string>& list); + /** + * Accessor to data structures + * @return CodecOrder& The list that reflects the user's choice + */ + inline CodecOrder& getActiveCodecs (void) { + return _codecOrder; + } + void setActiveCodecs (const std::vector <std::string>& list); + + inline std::string getRingtonePath (void) { + return _ringtonePath; + } + inline void setRingtonePath (std::string path) { + _ringtonePath = path; + } + + inline bool getRingtoneEnabled (void) { + return _ringtoneEnabled; + } + inline void setRingtoneEnabled (bool enabl) { + _ringtoneEnabled = enabl; + } + + inline std::string getDisplayName (void) { + return _displayName; + } + inline void setDisplayName (std::string name) { + _displayName = name; + } + + std::string getUseragent (void) { + return _useragent; + } + void setUseragent (std::string ua) { + _useragent = ua; + } private: // copy constructor - Account(const Account& rh); + Account (const Account& rh); // assignment operator - Account& operator=(const Account& rh); + Account& operator= (const Account& rh); - void loadAudioCodecs (void); + void loadAudioCodecs (void); protected: /** @@ -290,21 +385,47 @@ class Account{ std::string _type; /* - * The general, protocol neutral registration + * The general, protocol neutral registration * state of the account */ RegistrationState _registrationState; - + /* * Details about the registration state. - * This is a protocol Code:Description pair. + * This is a protocol Code:Description pair. */ std::pair<int, std::string> _registrationStateDetailed; - /** - * Vector containing the order of the codecs - */ - CodecOrder _codecOrder; + /** + * Vector containing the order of the codecs + */ + CodecOrder _codecOrder; + + /** + * List of codec obtained when parsing configuration and used + * to generate codec order list + */ + std::string _codecStr; + + /** + * Ringtone .au file used for this account + */ + std::string _ringtonePath; + + /** + * Play ringtone when receiving a call + */ + bool _ringtoneEnabled; + + /** + * Display name when calling + */ + std::string _displayName; + + /** + * Useragent used for registration + */ + std::string _useragent; }; diff --git a/sflphone-common/src/accountcreator.cpp b/sflphone-common/src/accountcreator.cpp index c0b2abc383a972223cff6d44928d7c916f00b1be..92bfa59376d1a3c8c8e8479ef4007802342a6f5c 100644 --- a/sflphone-common/src/accountcreator.cpp +++ b/sflphone-common/src/accountcreator.cpp @@ -50,19 +50,26 @@ AccountCreator::createAccount (AccountType type, AccountID accountID) { switch (type) { - case SIP_ACCOUNT: + case SIP_ACCOUNT: { + _debug ("AccountCreator: create account %s", accountID.c_str()); return new SIPAccount (accountID); break; - - case SIP_DIRECT_IP_ACCOUNT: + } + case SIP_DIRECT_IP_ACCOUNT: { + _debug ("AccountCreator: create account IP2IP_PROFILE"); return new SIPAccount (IP2IP_PROFILE); break; + } #ifdef USE_IAX - case IAX_ACCOUNT: + case IAX_ACCOUNT: { + _debug ("AccountCreator: create account %s", accountID.c_str()); return new IAXAccount (accountID); break; + } #endif + default: + _error ("AccountCreator: Error: unknown account type"); } return 0; diff --git a/sflphone-common/src/accountcreator.h b/sflphone-common/src/accountcreator.h index b0c93191201635f99c84d5061478f178865e3000..71f8e36ab8295d886fb205c15d9a3516445df07f 100644 --- a/sflphone-common/src/accountcreator.h +++ b/sflphone-common/src/accountcreator.h @@ -2,17 +2,17 @@ * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com> * Author: Yan Morin <yan.morin@savoirfairelinux.com> - * + * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -39,24 +39,25 @@ class Account; * @file accountcreator.h * @brief Create protocol-specific account */ -class AccountCreator{ -public: - ~AccountCreator(); - /** - * Public account type - */ - enum AccountType {SIP_ACCOUNT, SIP_DIRECT_IP_ACCOUNT, IAX_ACCOUNT }; - - /** - * Create a new account or null - * @param type type of the account - * @param accountID accountID (must be unique for each account) - */ - static Account* createAccount(AccountType type, AccountID accountID); +class AccountCreator +{ + public: + ~AccountCreator(); + /** + * Public account type + */ + enum AccountType {SIP_ACCOUNT, SIP_DIRECT_IP_ACCOUNT, IAX_ACCOUNT }; + + /** + * Create a new account or null + * @param type type of the account + * @param accountID accountID (must be unique for each account) + */ + static Account* createAccount (AccountType type, AccountID accountID); -private: - /** Hidden constructor */ - AccountCreator(); + private: + /** Hidden constructor */ + AccountCreator(); }; #endif diff --git a/sflphone-common/src/audio/algorithm.h b/sflphone-common/src/audio/algorithm.h index 6f147471860f97504107db69ae1ba9294c518632..84f9d8136cc9b2f9b2441a75b613a8077c8e1ed6 100644 --- a/sflphone-common/src/audio/algorithm.h +++ b/sflphone-common/src/audio/algorithm.h @@ -35,45 +35,46 @@ /** * \class Algorithm - * + * * Abstract interface used to implement audio processing algorithm */ -class Algorithm { +class Algorithm +{ - public: + public: - virtual void reset(void) = 0; + virtual void reset (void) = 0; - /** - * Put data to be processed - */ - virtual void putData(SFLDataFormat *inputData, int nbBytes) = 0; + /** + * Put data to be processed + */ + virtual void putData (SFLDataFormat *inputData, int nbBytes) = 0; - /** - * - */ - virtual int getData(SFLDataFormat *outputData) = 0; + /** + * + */ + virtual int getData (SFLDataFormat *outputData) = 0; - /** - * Class implementing this interface must define this function - * for audio processing that require synchronization between spkrdata and - */ - virtual void process(SFLDataFormat *inputData, int nbBytes) = 0; + /** + * Class implementing this interface must define this function + * for audio processing that require synchronization between spkrdata and + */ + virtual void process (SFLDataFormat *inputData, int nbBytes) = 0; - /** - * Class implementing this interface must define this function - * for audio processing that require synchronization between spkrdata and - */ - virtual int process(SFLDataFormat *inputData, SFLDataFormat *outputData, int nbBytes) = 0; + /** + * Class implementing this interface must define this function + * for audio processing that require synchronization between spkrdata and + */ + virtual int process (SFLDataFormat *inputData, SFLDataFormat *outputData, int nbBytes) = 0; - /** - * Class implementing this interface must define this function - * for audio processing that require synchronization between spkr and mic - * \param micData - * \param spkrData - * \param outputData - */ - virtual void process(SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes) = 0; + /** + * Class implementing this interface must define this function + * for audio processing that require synchronization between spkr and mic + * \param micData + * \param spkrData + * \param outputData + */ + virtual void process (SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes) = 0; }; diff --git a/sflphone-common/src/audio/alsa/alsalayer.cpp b/sflphone-common/src/audio/alsa/alsalayer.cpp index f5eeba6d8ee74faecb902bde7966484a84ab1d95..895a072e7609a68d3007176795340073b69f18d9 100644 --- a/sflphone-common/src/audio/alsa/alsalayer.cpp +++ b/sflphone-common/src/audio/alsa/alsalayer.cpp @@ -41,8 +41,8 @@ AlsaLayer::AlsaLayer (ManagerImpl* manager) , _PlaybackHandle (NULL) , _RingtoneHandle (NULL) , _CaptureHandle (NULL) - , _periodSize() - , _audioPlugin() + , _periodSize (160) + , _audioPlugin ("default") , IDSoundCards() , _is_prepared_playback (false) , _is_prepared_capture (false) @@ -60,6 +60,8 @@ AlsaLayer::AlsaLayer (ManagerImpl* manager) // _audioThread = NULL; _urgentRingBuffer.createReadPointer(); + _audioPlugin = AudioLayer::_manager->audioPreference.getPlugin(); + AudioLayer::_echocancelstate = true; AudioLayer::_noisesuppressstate = true; } @@ -900,13 +902,13 @@ AlsaLayer::soundCardGetIndex (std::string description) void AlsaLayer::audioCallback (void) { - int toGet, urgentAvailBytes, normalAvailBytes, maxBytes; + int toGet, urgentAvailBytes, normalAvailBytes; unsigned short spkrVolume, micVolume; AudioLoop *tone; AudioLoop *file_tone; - SFLDataFormat *out; - SFLDataFormat *rsmpl_out; + SFLDataFormat *out = NULL; + SFLDataFormat *rsmpl_out = NULL; spkrVolume = _manager->getSpkrVolume(); micVolume = _manager->getMicVolume(); @@ -932,35 +934,44 @@ void AlsaLayer::audioCallback (void) // Urgent data (dtmf, incoming call signal) come first. toGet = (urgentAvailBytes < (int) (playbackAvailBytes)) ? urgentAvailBytes : playbackAvailBytes; out = (SFLDataFormat*) malloc (toGet); - _urgentRingBuffer.Get (out, toGet, spkrVolume); - /* Play the sound */ - write (out, toGet, _PlaybackHandle); + if (out) { + _urgentRingBuffer.Get (out, toGet, spkrVolume); + write (out, toGet, _PlaybackHandle); + free (out); + } - free (out); - out=0; + out=NULL; // Consume the regular one as well (same amount of bytes) getMainBuffer()->discard (toGet); } else { - if (tone) { + normalAvailBytes = getMainBuffer()->availForGet(); + + if (tone && (normalAvailBytes <= 0)) { out = (SFLDataFormat *) malloc (playbackAvailBytes); - tone->getNext (out, playbackAvailSmpl, spkrVolume); - write (out , playbackAvailBytes, _PlaybackHandle); - free (out); - out = 0; + if (out) { + tone->getNext (out, playbackAvailSmpl, spkrVolume); + write (out , playbackAvailBytes, _PlaybackHandle); + free (out); + } + + out = NULL; - } else if (file_tone && !_RingtoneHandle) { + } else if (file_tone && !_RingtoneHandle && (normalAvailBytes <= 0)) { out = (SFLDataFormat *) malloc (playbackAvailBytes); - file_tone->getNext (out, playbackAvailSmpl, spkrVolume); - write (out, playbackAvailBytes, _PlaybackHandle); - free (out); + if (out) { + file_tone->getNext (out, playbackAvailSmpl, spkrVolume); + write (out, playbackAvailBytes, _PlaybackHandle); + free (out); + } + out = NULL; } else { @@ -982,8 +993,6 @@ void AlsaLayer::audioCallback (void) } - - normalAvailBytes = getMainBuffer()->availForGet(); toGet = (normalAvailBytes < (int) maxNbBytesToGet) ? normalAvailBytes : maxNbBytesToGet; out = (SFLDataFormat*) malloc (maxNbBytesToGet); @@ -998,19 +1007,16 @@ void AlsaLayer::audioCallback (void) if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) { - - rsmpl_out = (SFLDataFormat*) malloc (playbackAvailBytes*2); - // Do sample rate conversion int nb_sample_down = toGet / sizeof (SFLDataFormat); - int nbSample = _converter->upsampleData ( (SFLDataFormat*) out, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, nb_sample_down); + if (rsmpl_out) { + rsmpl_out = (SFLDataFormat*) malloc (playbackAvailBytes); + int nbSample = _converter->upsampleData ( (SFLDataFormat*) out, rsmpl_out, _mainBufferSampleRate, _audioSampleRate, nb_sample_down); + write (rsmpl_out, nbSample*sizeof (SFLDataFormat), _PlaybackHandle); + free (rsmpl_out); + } - - - write (rsmpl_out, nbSample*sizeof (SFLDataFormat), _PlaybackHandle); - - free (rsmpl_out); rsmpl_out = 0; } else { @@ -1020,7 +1026,7 @@ void AlsaLayer::audioCallback (void) } // Copy far-end signal in echo canceller to adapt filter coefficient - AudioLayer::_echoCanceller->putData (out, toGet); + // AudioLayer::_echoCanceller->putData (out, toGet); } else { @@ -1028,17 +1034,20 @@ void AlsaLayer::audioCallback (void) SFLDataFormat *zeros = (SFLDataFormat*) malloc (playbackAvailBytes); - bzero (zeros, playbackAvailBytes); - write (zeros, playbackAvailBytes, _PlaybackHandle); + if (zeros) { + bzero (zeros, playbackAvailBytes); + write (zeros, playbackAvailBytes, _PlaybackHandle); + free (zeros); + } - free (zeros); + zeros = NULL; } } _urgentRingBuffer.Discard (toGet); free (out); - out = 0; + out = NULL; } @@ -1052,10 +1061,13 @@ void AlsaLayer::audioCallback (void) // _debug("RINGTONE: %d", ringtoneAvailSmpl); out = (SFLDataFormat *) malloc (ringtoneAvailBytes); - file_tone->getNext (out, ringtoneAvailSmpl, spkrVolume); - write (out, ringtoneAvailBytes, _RingtoneHandle); - free (out); + if (out) { + file_tone->getNext (out, ringtoneAvailSmpl, spkrVolume); + write (out, ringtoneAvailBytes, _RingtoneHandle); + free (out); + } + out = NULL; } else if (_RingtoneHandle) { @@ -1064,10 +1076,13 @@ void AlsaLayer::audioCallback (void) int ringtoneAvailBytes = ringtoneAvailSmpl*sizeof (SFLDataFormat); out = (SFLDataFormat *) malloc (ringtoneAvailBytes); - memset (out, 0, ringtoneAvailBytes); - write (out, ringtoneAvailBytes, _RingtoneHandle); - free (out); + if (out) { + memset (out, 0, ringtoneAvailBytes); + write (out, ringtoneAvailBytes, _RingtoneHandle); + free (out); + } + out = NULL; } @@ -1076,13 +1091,10 @@ void AlsaLayer::audioCallback (void) int micAvailPut; int toPut; - SFLDataFormat* in; + SFLDataFormat* in = NULL; SFLDataFormat echoCancelledMic[5000]; memset (echoCancelledMic, 0, 5000); - // snd_pcm_sframes_t micAvailAlsa; - in = 0; - if (is_capture_running()) { micAvailBytes = snd_pcm_avail_update (_CaptureHandle); @@ -1094,9 +1106,9 @@ void AlsaLayer::audioCallback (void) in = (SFLDataFormat*) malloc (toPut * sizeof (SFLDataFormat)); toPut = read (in, toPut* sizeof (SFLDataFormat)); - adjustVolume (in, toPut, SFL_PCM_CAPTURE); + if (in) { + adjustVolume (in, toPut, SFL_PCM_CAPTURE); - if (in != 0) { int _mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate(); if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) { @@ -1112,10 +1124,10 @@ void AlsaLayer::audioCallback (void) _audiofilter->processAudio (rsmpl_out, nbSample*sizeof (SFLDataFormat)); // echo cancellation processing - int sampleready = AudioLayer::_echoCanceller->processAudio (rsmpl_out, echoCancelledMic, nbSample*sizeof (SFLDataFormat)); + // int sampleready = AudioLayer::_echoCanceller->processAudio (rsmpl_out, echoCancelledMic, nbSample*sizeof (SFLDataFormat)); - // getMainBuffer()->putData (rsmpl_out, nbSample * sizeof (SFLDataFormat), 100); - getMainBuffer()->putData (echoCancelledMic, sampleready*sizeof (SFLDataFormat), 100); + getMainBuffer()->putData (rsmpl_out, nbSample * sizeof (SFLDataFormat), 100); + // getMainBuffer()->putData (echoCancelledMic, sampleready*sizeof (SFLDataFormat), 100); free (rsmpl_out); rsmpl_out = 0; @@ -1125,12 +1137,14 @@ void AlsaLayer::audioCallback (void) SFLDataFormat* filter_out = (SFLDataFormat*) malloc (framesPerBufferAlsa * sizeof (SFLDataFormat)); - _audiofilter->processAudio (in, filter_out, toPut); - - int sampleready = AudioLayer::_echoCanceller->processAudio (filter_out, echoCancelledMic, toPut); + if (filter_out) { + _audiofilter->processAudio (in, filter_out, toPut); + // int sampleready = AudioLayer::_echoCanceller->processAudio (filter_out, echoCancelledMic, toPut); + // getMainBuffer()->putData (echoCancelledMic, sampleready*sizeof (SFLDataFormat), 100); + getMainBuffer()->putData (filter_out, toPut, 100); + free (filter_out); + } - getMainBuffer()->putData (echoCancelledMic, sampleready*sizeof (SFLDataFormat), 100); - free (rsmpl_out); } } diff --git a/sflphone-common/src/audio/alsa/alsalayer.h b/sflphone-common/src/audio/alsa/alsalayer.h index 8bcacb28987353f95c7a422e80aa9a69b2ee55f5..ca42673f39fbd198585b09b10fcf1bc7fd4819b0 100644 --- a/sflphone-common/src/audio/alsa/alsalayer.h +++ b/sflphone-common/src/audio/alsa/alsalayer.h @@ -7,12 +7,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -45,269 +45,310 @@ typedef std::pair<int , std::string> HwIDPair; /** * @file AlsaLayer.h - * @brief Main sound class. Manages the data transfers between the application and the hardware. + * @brief Main sound class. Manages the data transfers between the application and the hardware. */ -class AlsaLayer : public AudioLayer { - public: - /** - * Constructor - * @param manager An instance of managerimpl - */ - AlsaLayer( ManagerImpl* manager ); - - /** - * Destructor - */ - ~AlsaLayer(void); - - bool closeLayer( void ); - - /** - * Check if no devices are opened, otherwise close them. - * Then open the specified devices by calling the private functions open_device - * @param indexIn The number of the card chosen for capture - * @param indexOut The number of the card chosen for playback - * @param sampleRate The sample rate - * @param frameSize The frame size - * @param stream To indicate which kind of stream you want to open - * SFL_PCM_CAPTURE - * SFL_PCM_PLAYBACK - * SFL_PCM_BOTH - * @param plugin The alsa plugin ( dmix , default , front , surround , ...) - */ - bool openDevice(int indexIn, int indexOut, int indexRing, int sampleRate, int frameSize, int stream, std::string plugin); - - /** - * Start the capture stream and prepare the playback stream. - * The playback starts accordingly to its threshold - * ALSA Library API - */ - void startStream(void); - - /** - * Stop the playback and capture streams. - * Drops the pending frames and put the capture and playback handles to PREPARED state - * ALSA Library API - */ - void stopStream(void); - - /** - * Query the capture device for number of bytes available in the hardware ring buffer - * @return int The number of bytes available - */ - int canGetMic(); - - /** - * Get data from the capture device - * @param buffer The buffer for data - * @param toCopy The number of bytes to get - * @return int The number of bytes acquired ( 0 if an error occured) - */ - int getMic(void * buffer, int toCopy); - - /** - * Concatenate two strings. Used to build a valid pcm device name. - * @param plugin the alsa PCM name - * @param card the sound card number - * @param subdevice the subdevice number - * @return std::string the concatenated string - */ - std::string buildDeviceTopo( std::string plugin, int card, int subdevice ); - - /** - * Scan the sound card available on the system - * @param stream To indicate whether we are looking for capture devices or playback devices - * SFL_PCM_CAPTURE - * SFL_PCM_PLAYBACK - * SFL_PCM_BOTH - * @return std::vector<std::string> The vector containing the string description of the card - */ - std::vector<std::string> getSoundCardsInfo( int stream ); - - /** - * Check if the given index corresponds to an existing sound card and supports the specified streaming mode - * @param card An index - * @param stream The stream mode - * SFL_PCM_CAPTURE - * SFL_PCM_PLAYBACK - * SFL_PCM_BOTH - * @return bool True if it exists and supports the mode - * false otherwise - */ - bool soundCardIndexExist( int card , int stream ); - - /** - * An index is associated with its string description - * @param description The string description - * @return int Its index - */ - int soundCardGetIndex( std::string description ); - - /** - * Get the current audio plugin. - * @return std::string The name of the audio plugin - */ - std::string getAudioPlugin( void ) { return _audioPlugin; } - - void audioCallback (void); - - bool isCaptureActive (void); - - /** - * Get the echo canceller state - * @return true if echo cancel activated - */ - virtual bool getEchoCancelState(void) { return AudioLayer::_echocancelstate; } - - /** - * Set the echo canceller state - * @param state true if echocancel active, false elsewhere - */ - virtual void setEchoCancelState(bool state); - - /** - * Get the noise suppressor state - * @return true if noise suppressor activated - */ - virtual bool getNoiseSuppressState(void) { return AudioLayer::_noisesuppressstate; } - - /** - * Set the noise suppressor state - * @param state true if noise suppressor active, false elsewhere - */ - virtual void setNoiseSuppressState(bool state); - - private: - - // Copy Constructor - AlsaLayer(const AlsaLayer& rh); - - // Assignment Operator - AlsaLayer& operator=( const AlsaLayer& rh); - - bool is_playback_prepared (void) { return _is_prepared_playback; } - bool is_capture_prepared (void) { return _is_prepared_capture; } - void prepare_playback (void) { _is_prepared_playback = true; } - void prepare_capture (void) { _is_prepared_capture = true; } - bool is_capture_running (void) { return _is_running_capture; } - bool is_playback_running (void) { return _is_running_playback; } - void start_playback (void) { _is_running_playback = true; } - void stop_playback (void) { _is_running_playback = false; _is_prepared_playback = false; } - void start_capture (void) { _is_running_capture = true; } - void stop_capture (void) { _is_running_capture = false; _is_prepared_capture = false; } - void close_playback (void) { _is_open_playback = false; } - void close_capture (void) { _is_open_capture = false; } - void open_playback (void) { _is_open_playback = true; } - void open_capture (void) { _is_open_capture = true; } - bool is_capture_open (void) { return _is_open_capture; } - bool is_playback_open (void) { return _is_open_playback; } - - /** - * Drop the pending frames and close the capture device - * ALSA Library API - */ - void closeCaptureStream( void ); - void stopCaptureStream( void ); - void startCaptureStream( void ); - void prepareCaptureStream( void ); - - void closePlaybackStream( void ); - void stopPlaybackStream( void ); - void startPlaybackStream( void ); - void preparePlaybackStream( void ); - - /** - * Open the specified device. - * ALSA Library API - * @param pcm_p The string name for the playback device - * @param pcm_c The string name for the capture device - * @param flag To indicate which kind of stream you want to open - * SFL_PCM_CAPTURE - * SFL_PCM_PLAYBACK - * SFL_PCM_BOTH - * @return true if successful - * false otherwise - */ - bool open_device( std::string pcm_p, std::string pcm_c, std::string pcm_r, int flag); - - bool alsa_set_params( snd_pcm_t *pcm_handle, int type, int rate ); - - /** - * Copy a data buffer in the internal ring buffer - * ALSA Library API - * @param buffer The data to be copied - * @param length The size of the buffer - * @return int The number of frames actually copied - */ - int write( void* buffer, int length, snd_pcm_t *handle); - - /** - * Read data from the internal ring buffer - * ALSA Library API - * @param buffer The buffer to stock the read data - * @param toCopy The number of bytes to get - * @return int The number of frames actually read - */ - int read( void* buffer, int toCopy); - - /** - * Recover from XRUN state for capture - * ALSA Library API - */ - void handle_xrun_capture( void ); - - /** - * Recover from XRUN state for playback - * ALSA Library API - */ - void handle_xrun_playback( snd_pcm_t *handle ); - - void* adjustVolume( void* buffer , int len, int stream ); - - /** - * Handles to manipulate playback stream - * ALSA Library API - */ - snd_pcm_t* _PlaybackHandle; - - /** - * Handles to manipulate ringtone stream - * - */ - snd_pcm_t *_RingtoneHandle; - - /** - * Handles to manipulate capture stream - * ALSA Library API - */ - snd_pcm_t* _CaptureHandle; - - /** - * Alsa parameter - Size of a period in the hardware ring buffer - */ - snd_pcm_uframes_t _periodSize; - - /** - * name of the alsa audio plugin used - */ - std::string _audioPlugin; - - /** Vector to manage all soundcard index - description association of the system */ - std::vector<HwIDPair> IDSoundCards; - - bool _is_prepared_playback; - bool _is_prepared_capture; - bool _is_running_playback; - bool _is_running_capture; - bool _is_open_playback; - bool _is_open_capture; - bool _trigger_request; - - AudioThread* _audioThread; - - /** Sample rate converter object */ - SamplerateConverter* _converter; +class AlsaLayer : public AudioLayer +{ + public: + /** + * Constructor + * @param manager An instance of managerimpl + */ + AlsaLayer (ManagerImpl* manager); + + /** + * Destructor + */ + ~AlsaLayer (void); + + bool closeLayer (void); + + /** + * Check if no devices are opened, otherwise close them. + * Then open the specified devices by calling the private functions open_device + * @param indexIn The number of the card chosen for capture + * @param indexOut The number of the card chosen for playback + * @param sampleRate The sample rate + * @param frameSize The frame size + * @param stream To indicate which kind of stream you want to open + * SFL_PCM_CAPTURE + * SFL_PCM_PLAYBACK + * SFL_PCM_BOTH + * @param plugin The alsa plugin ( dmix , default , front , surround , ...) + */ + bool openDevice (int indexIn, int indexOut, int indexRing, int sampleRate, int frameSize, int stream, std::string plugin); + + /** + * Start the capture stream and prepare the playback stream. + * The playback starts accordingly to its threshold + * ALSA Library API + */ + void startStream (void); + + /** + * Stop the playback and capture streams. + * Drops the pending frames and put the capture and playback handles to PREPARED state + * ALSA Library API + */ + void stopStream (void); + + /** + * Query the capture device for number of bytes available in the hardware ring buffer + * @return int The number of bytes available + */ + int canGetMic(); + + /** + * Get data from the capture device + * @param buffer The buffer for data + * @param toCopy The number of bytes to get + * @return int The number of bytes acquired ( 0 if an error occured) + */ + int getMic (void * buffer, int toCopy); + + /** + * Concatenate two strings. Used to build a valid pcm device name. + * @param plugin the alsa PCM name + * @param card the sound card number + * @param subdevice the subdevice number + * @return std::string the concatenated string + */ + std::string buildDeviceTopo (std::string plugin, int card, int subdevice); + + /** + * Scan the sound card available on the system + * @param stream To indicate whether we are looking for capture devices or playback devices + * SFL_PCM_CAPTURE + * SFL_PCM_PLAYBACK + * SFL_PCM_BOTH + * @return std::vector<std::string> The vector containing the string description of the card + */ + std::vector<std::string> getSoundCardsInfo (int stream); + + /** + * Check if the given index corresponds to an existing sound card and supports the specified streaming mode + * @param card An index + * @param stream The stream mode + * SFL_PCM_CAPTURE + * SFL_PCM_PLAYBACK + * SFL_PCM_BOTH + * @return bool True if it exists and supports the mode + * false otherwise + */ + bool soundCardIndexExist (int card , int stream); + + /** + * An index is associated with its string description + * @param description The string description + * @return int Its index + */ + int soundCardGetIndex (std::string description); + + /** + * Get the current audio plugin. + * @return std::string The name of the audio plugin + */ + std::string getAudioPlugin (void) { + return _audioPlugin; + } + + void audioCallback (void); + + bool isCaptureActive (void); + + /** + * Get the echo canceller state + * @return true if echo cancel activated + */ + virtual bool getEchoCancelState (void) { + return AudioLayer::_echocancelstate; + } + + /** + * Set the echo canceller state + * @param state true if echocancel active, false elsewhere + */ + virtual void setEchoCancelState (bool state); + + /** + * Get the noise suppressor state + * @return true if noise suppressor activated + */ + virtual bool getNoiseSuppressState (void) { + return AudioLayer::_noisesuppressstate; + } + + /** + * Set the noise suppressor state + * @param state true if noise suppressor active, false elsewhere + */ + virtual void setNoiseSuppressState (bool state); + + private: + + // Copy Constructor + AlsaLayer (const AlsaLayer& rh); + + // Assignment Operator + AlsaLayer& operator= (const AlsaLayer& rh); + + bool is_playback_prepared (void) { + return _is_prepared_playback; + } + bool is_capture_prepared (void) { + return _is_prepared_capture; + } + void prepare_playback (void) { + _is_prepared_playback = true; + } + void prepare_capture (void) { + _is_prepared_capture = true; + } + bool is_capture_running (void) { + return _is_running_capture; + } + bool is_playback_running (void) { + return _is_running_playback; + } + void start_playback (void) { + _is_running_playback = true; + } + void stop_playback (void) { + _is_running_playback = false; + _is_prepared_playback = false; + } + void start_capture (void) { + _is_running_capture = true; + } + void stop_capture (void) { + _is_running_capture = false; + _is_prepared_capture = false; + } + void close_playback (void) { + _is_open_playback = false; + } + void close_capture (void) { + _is_open_capture = false; + } + void open_playback (void) { + _is_open_playback = true; + } + void open_capture (void) { + _is_open_capture = true; + } + bool is_capture_open (void) { + return _is_open_capture; + } + bool is_playback_open (void) { + return _is_open_playback; + } + + /** + * Drop the pending frames and close the capture device + * ALSA Library API + */ + void closeCaptureStream (void); + void stopCaptureStream (void); + void startCaptureStream (void); + void prepareCaptureStream (void); + + void closePlaybackStream (void); + void stopPlaybackStream (void); + void startPlaybackStream (void); + void preparePlaybackStream (void); + + /** + * Open the specified device. + * ALSA Library API + * @param pcm_p The string name for the playback device + * @param pcm_c The string name for the capture device + * @param flag To indicate which kind of stream you want to open + * SFL_PCM_CAPTURE + * SFL_PCM_PLAYBACK + * SFL_PCM_BOTH + * @return true if successful + * false otherwise + */ + bool open_device (std::string pcm_p, std::string pcm_c, std::string pcm_r, int flag); + + bool alsa_set_params (snd_pcm_t *pcm_handle, int type, int rate); + + /** + * Copy a data buffer in the internal ring buffer + * ALSA Library API + * @param buffer The data to be copied + * @param length The size of the buffer + * @return int The number of frames actually copied + */ + int write (void* buffer, int length, snd_pcm_t *handle); + + /** + * Read data from the internal ring buffer + * ALSA Library API + * @param buffer The buffer to stock the read data + * @param toCopy The number of bytes to get + * @return int The number of frames actually read + */ + int read (void* buffer, int toCopy); + + /** + * Recover from XRUN state for capture + * ALSA Library API + */ + void handle_xrun_capture (void); + + /** + * Recover from XRUN state for playback + * ALSA Library API + */ + void handle_xrun_playback (snd_pcm_t *handle); + + void* adjustVolume (void* buffer , int len, int stream); + + /** + * Handles to manipulate playback stream + * ALSA Library API + */ + snd_pcm_t* _PlaybackHandle; + + /** + * Handles to manipulate ringtone stream + * + */ + snd_pcm_t *_RingtoneHandle; + + /** + * Handles to manipulate capture stream + * ALSA Library API + */ + snd_pcm_t* _CaptureHandle; + + /** + * Alsa parameter - Size of a period in the hardware ring buffer + */ + snd_pcm_uframes_t _periodSize; + + /** + * name of the alsa audio plugin used + */ + std::string _audioPlugin; + + /** Vector to manage all soundcard index - description association of the system */ + std::vector<HwIDPair> IDSoundCards; + + bool _is_prepared_playback; + bool _is_prepared_capture; + bool _is_running_playback; + bool _is_running_capture; + bool _is_open_playback; + bool _is_open_capture; + bool _trigger_request; + + AudioThread* _audioThread; + + /** Sample rate converter object */ + SamplerateConverter* _converter; }; diff --git a/sflphone-common/src/audio/audiodevice.h b/sflphone-common/src/audio/audiodevice.h index 306afbeb8c24bc1d41a111f5b95d3683c34eb6e9..4fa6c25e922a934f7b11b247794ed90c747c2f9c 100644 --- a/sflphone-common/src/audio/audiodevice.h +++ b/sflphone-common/src/audio/audiodevice.h @@ -6,12 +6,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -40,57 +40,66 @@ * @brief Container device for attribute storage * Have almost only get/set method */ -class AudioDevice { -public: - /** - * Constructor - * @param id Identifier - * @param name Name - */ - AudioDevice(int id, const std::string& name); - - /** - * Destructor - */ - ~AudioDevice(); - - /** Default sample rate */ - const static double DEFAULT_RATE; - - /** - * Read accessor to the ID - * @return int The ID of the audiodevice - */ - int getId() { return _id; } - - /** - * Read accessor to the name - * @return std::string& A string description - */ - const std::string& getName() {return _name; } - - /** - * Write accessor to the sample rate - * @param rate The sample rate - */ - void setRate(double rate) { _rate = rate;} - - /** - * Read accessor to the sample rate - * @return double The sample rate - */ - double getRate() { return _rate; } - -private: - - /** Integer id of the device, can not be 0 */ - int _id; - - /** Name of the device */ - std::string _name; - - /** Default rate in Hz, like 8000.0, default is AudioDevice::DEFAULT_RATE */ - double _rate; +class AudioDevice +{ + public: + /** + * Constructor + * @param id Identifier + * @param name Name + */ + AudioDevice (int id, const std::string& name); + + /** + * Destructor + */ + ~AudioDevice(); + + /** Default sample rate */ + const static double DEFAULT_RATE; + + /** + * Read accessor to the ID + * @return int The ID of the audiodevice + */ + int getId() { + return _id; + } + + /** + * Read accessor to the name + * @return std::string& A string description + */ + const std::string& getName() { + return _name; + } + + /** + * Write accessor to the sample rate + * @param rate The sample rate + */ + void setRate (double rate) { + _rate = rate; + } + + /** + * Read accessor to the sample rate + * @return double The sample rate + */ + double getRate() { + return _rate; + } + + private: + + /** Integer id of the device, can not be 0 */ + int _id; + + /** Name of the device */ + std::string _name; + + /** Default rate in Hz, like 8000.0, default is AudioDevice::DEFAULT_RATE */ + double _rate; }; #endif // _AUDIO_DEVICE_H_ diff --git a/sflphone-common/src/audio/audiolayer.h b/sflphone-common/src/audio/audiolayer.h index ab2a4559fa144d10278c53ba69c624ba6457eced..9859398d6728879af718bdb286c49ab2254bd3bf 100644 --- a/sflphone-common/src/audio/audiolayer.h +++ b/sflphone-common/src/audio/audiolayer.h @@ -1,19 +1,19 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Yan Morin <yan.morin@savoirfairelinux.com> - * Author: Jerome Oufella <jerome.oufella@savoirfairelinux.com> + * Author: Jerome Oufella <jerome.oufella@savoirfairelinux.com> * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -45,56 +45,56 @@ /** * @file audiolayer.h - * @brief Main sound class. Manages the data transfers between the application and the hardware. + * @brief Main sound class. Manages the data transfers between the application and the hardware. */ class ManagerImpl; -class AudioLayer { +class AudioLayer +{ private: //copy constructor - AudioLayer(const AudioLayer& rh); + AudioLayer (const AudioLayer& rh); // assignment operator - AudioLayer& operator=(const AudioLayer& rh); + AudioLayer& operator= (const AudioLayer& rh); public: /** * Constructor * @param manager An instance of managerimpl */ - AudioLayer( ManagerImpl* manager , int type ) - : _defaultVolume(100) - , _layerType( type ) - , _manager(manager) - , _urgentRingBuffer( SIZEBUF, default_id ) - , _indexIn ( 0 ) - , _indexOut ( 0 ) - , _audioSampleRate ( 0 ) - , _frameSize ( 0 ) - , _inChannel( 1 ) - , _outChannel ( 1 ) - , _errorMessage ( 0 ) - , _mutex () - { - - } + AudioLayer (ManagerImpl* manager , int type) + : _defaultVolume (100) + , _layerType (type) + , _manager (manager) + , _urgentRingBuffer (SIZEBUF, default_id) + , _indexIn (0) + , _indexOut (0) + , _audioSampleRate (0) + , _frameSize (0) + , _inChannel (1) + , _outChannel (1) + , _errorMessage (0) + , _mutex () { + + } /** * Destructor */ - virtual ~AudioLayer(void) {} + virtual ~AudioLayer (void) {} - virtual bool closeLayer( void ) = 0; + virtual bool closeLayer (void) = 0; /** * Check if no devices are opened, otherwise close them. * Then open the specified devices by calling the private functions open_device * @param indexIn The number of the card chosen for capture * @param indexOut The number of the card chosen for playback - * @param sampleRate The sample rate + * @param sampleRate The sample rate * @param frameSize The frame size * @param stream To indicate which kind of stream you want to open * SFL_PCM_CAPTURE @@ -102,30 +102,30 @@ class AudioLayer { * SFL_PCM_BOTH * @param plugin The alsa plugin ( dmix , default , front , surround , ...) */ - virtual bool openDevice(int indexIn, int indexOut, int indexRing, int sampleRate, int frameSize, int stream , std::string plugin) = 0; + virtual bool openDevice (int indexIn, int indexOut, int indexRing, int sampleRate, int frameSize, int stream , std::string plugin) = 0; /** - * Start the capture stream and prepare the playback stream. + * Start the capture stream and prepare the playback stream. * The playback starts accordingly to its threshold * ALSA Library API */ - virtual void startStream(void) = 0; + virtual void startStream (void) = 0; /** - * Stop the playback and capture streams. + * Stop the playback and capture streams. * Drops the pending frames and put the capture and playback handles to PREPARED state * ALSA Library API */ - virtual void stopStream(void) = 0; + virtual void stopStream (void) = 0; /** * Send a chunk of data to the hardware buffer to start the playback - * Copy data in the urgent buffer. + * Copy data in the urgent buffer. * @param buffer The buffer containing the data to be played ( ringtones ) * @param toCopy The size of the buffer * @return int The number of bytes copied in the urgent buffer */ - int putUrgent(void* buffer, int toCopy); + int putUrgent (void* buffer, int toCopy); /** * Put voice data in the main sound buffer @@ -133,7 +133,7 @@ class AudioLayer { * @param toCopy The size of the buffer * @return int The number of bytes copied */ - int putMain(void* buffer, int toCopy, CallID call_id = default_id); + int putMain (void* buffer, int toCopy, CallID call_id = default_id); void flushMain (void); @@ -147,116 +147,143 @@ class AudioLayer { * @param error The error code * Could be: ALSA_PLAYBACK_DEVICE * ALSA_CAPTURE_DEVICE - */ - void setErrorMessage(const int& error) { _errorMessage = error; } + */ + void setErrorMessage (const int& error) { + _errorMessage = error; + } /** * Read accessor to the error state * @return int The error code */ - int getErrorMessage() { return _errorMessage; } + int getErrorMessage() { + return _errorMessage; + } /** * Get the index of the audio card for capture * @return int The index of the card used for capture * 0 for the first available card on the system, 1 ... */ - int getIndexIn() { return _indexIn; } + int getIndexIn() { + return _indexIn; + } /** * Get the index of the audio card for playback * @return int The index of the card used for playback * 0 for the first available card on the system, 1 ... */ - int getIndexOut() { return _indexOut; } + int getIndexOut() { + return _indexOut; + } - /** - * Get the index of the audio card for ringtone (could be differnet from playback) - * @return int The index of the card used for ringtone - * 0 for the first available card on the system, 1 ... - */ - int getIndexRing() {return _indexRing; } + /** + * Get the index of the audio card for ringtone (could be differnet from playback) + * @return int The index of the card used for ringtone + * 0 for the first available card on the system, 1 ... + */ + int getIndexRing() { + return _indexRing; + } /** * Get the sample rate of the audio layer * @return unsigned int The sample rate * default: 44100 HZ */ - unsigned int getSampleRate() { return _audioSampleRate; } + unsigned int getSampleRate() { + return _audioSampleRate; + } /** * Get the frame size of the audio layer * @return unsigned int The frame size * default: 20 ms */ - unsigned int getFrameSize() { return _frameSize; } + unsigned int getFrameSize() { + return _frameSize; + } - /** - * Get the layer type for this instance (either Alsa or PulseAudio) - * @return unsigned int The layer type + /** + * Get the layer type for this instance (either Alsa or PulseAudio) + * @return unsigned int The layer type + * + */ + int getLayerType (void) { + return _layerType; + } + + /** + * Get a pointer to the application MainBuffer class. * - */ - int getLayerType( void ) { return _layerType; } + * In order to send signal to other parts of the application, one must pass through the mainbuffer. + * Audio instances must be registered into the MainBuffer and bound together via the ManagerImpl. + * + * @return MainBuffer* a pointer to the MainBuffer instance + */ + MainBuffer* getMainBuffer (void) { + return _mainBuffer; + } - /** - * Get a pointer to the application MainBuffer class. - * - * In order to send signal to other parts of the application, one must pass through the mainbuffer. - * Audio instances must be registered into the MainBuffer and bound together via the ManagerImpl. - * - * @return MainBuffer* a pointer to the MainBuffer instance + /** + * Set the mainbuffer once the audiolayer is created */ - MainBuffer* getMainBuffer( void ) { return _mainBuffer; } - - /** - * Set the mainbuffer once the audiolayer is created - */ - void setMainBuffer( MainBuffer* mainbuffer ) { _mainBuffer = mainbuffer; } + void setMainBuffer (MainBuffer* mainbuffer) { + _mainBuffer = mainbuffer; + } /** * Default volume for incoming RTP and Urgent sounds. */ unsigned short _defaultVolume; // 100 - - /** - * Set the audio recorder - */ - inline void setRecorderInstance (Recordable* rec) {_recorder = NULL; _recorder = rec;} - /** - * Get the audio recorder - */ - inline Recordable* getRecorderInstance (void) {return _recorder;} + /** + * Set the audio recorder + */ + inline void setRecorderInstance (Recordable* rec) { + _recorder = NULL; + _recorder = rec; + } - /** - * Get the echo canceller state - * @return true if echo cancel activated + /** + * Get the audio recorder */ - virtual bool getEchoCancelState(void) = 0; + inline Recordable* getRecorderInstance (void) { + return _recorder; + } + + /** + * Get the echo canceller state + * @return true if echo cancel activated + */ + virtual bool getEchoCancelState (void) = 0; - /** - * Set the echo canceller state - * @param state true if echocancel active, false elsewhere - */ - virtual void setEchoCancelState(bool state) = 0; + /** + * Set the echo canceller state + * @param state true if echocancel active, false elsewhere + */ + virtual void setEchoCancelState (bool state) = 0; - /** - * Get the noise suppressor state - * @return true if noise suppressor activated - */ - virtual bool getNoiseSuppressState(void) = 0; + /** + * Get the noise suppressor state + * @return true if noise suppressor activated + */ + virtual bool getNoiseSuppressState (void) = 0; - /** - * Set the noise suppressor state - * @param state true if noise suppressor active, false elsewhere - */ - virtual void setNoiseSuppressState(bool state) = 0; + /** + * Set the noise suppressor state + * @param state true if noise suppressor active, false elsewhere + */ + virtual void setNoiseSuppressState (bool state) = 0; - /** - * Get the mutex lock for the entire audio layer - */ - inline ost::Mutex* getMutexLock(void) { return &_mutex; } + /** + * Get the mutex lock for the entire audio layer + */ + inline ost::Mutex* getMutexLock (void) { + return &_mutex; + } protected: @@ -266,52 +293,52 @@ class AudioLayer { /** * Drop the pending frames and close the capture device */ - virtual void closeCaptureStream( void ) = 0; + virtual void closeCaptureStream (void) = 0; /** * Drop the pending frames and close the playback device */ - virtual void closePlaybackStream( void ) = 0; + virtual void closePlaybackStream (void) = 0; /** Augment coupling, reduce indirect access */ - ManagerImpl* _manager; + ManagerImpl* _manager; /** * Urgent ring buffer used for ringtones */ RingBuffer _urgentRingBuffer; - /** - * Instance of the MainBuffer for the whole application - * - * In order to send signal to other parts of the application, one must pass through the mainbuffer. - * Audio instances must be registered into the MainBuffer and bound together via the ManagerImpl. - * - */ - MainBuffer* _mainBuffer; + /** + * Instance of the MainBuffer for the whole application + * + * In order to send signal to other parts of the application, one must pass through the mainbuffer. + * Audio instances must be registered into the MainBuffer and bound together via the ManagerImpl. + * + */ + MainBuffer* _mainBuffer; - /** - * A pointer to the recordable instance (may be a call or a conference) - */ - Recordable* _recorder; + /** + * A pointer to the recordable instance (may be a call or a conference) + */ + Recordable* _recorder; /** - * Number of audio cards on which capture stream has been opened + * Number of audio cards on which capture stream has been opened */ int _indexIn; /** - * Number of audio cards on which playback stream has been opened + * Number of audio cards on which playback stream has been opened */ int _indexOut; - /** - * Number of audio cards on which ringtone stream has been opened - */ - int _indexRing; + /** + * Number of audio cards on which ringtone stream has been opened + */ + int _indexRing; /** - * Sample Rate SFLphone should send sound data to the sound card + * Sample Rate SFLphone should send sound data to the sound card * The value can be set in the user config file- now: 44100HZ */ unsigned int _audioSampleRate; @@ -319,36 +346,36 @@ class AudioLayer { /** * Length of the sound frame we capture or read in ms * The value can be set in the user config file - now: 20ms - */ + */ unsigned int _frameSize; /** * Input channel (mic) should be 1 mono */ - unsigned int _inChannel; + unsigned int _inChannel; /** * Output channel (stereo) should be 1 mono */ - unsigned int _outChannel; + unsigned int _outChannel; /** Contains the current error code */ int _errorMessage; - /** - * Lock for the entire audio layer - */ + /** + * Lock for the entire audio layer + */ ost::Mutex _mutex; - EchoCancel *_echoCancel; - AudioProcessing *_echoCanceller; + EchoCancel *_echoCancel; + AudioProcessing *_echoCanceller; - DcBlocker *_dcblocker; - AudioProcessing *_audiofilter; + DcBlocker *_dcblocker; + AudioProcessing *_audiofilter; - bool _echocancelstate; + bool _echocancelstate; - bool _noisesuppressstate; + bool _noisesuppressstate; }; diff --git a/sflphone-common/src/audio/audioloop.h b/sflphone-common/src/audio/audioloop.h index 98f01726f12317ae8c8b60e3bcba671f2ce41a8b..adaa4087b4b571941a0b0a38d92327e772a0c7bf 100644 --- a/sflphone-common/src/audio/audioloop.h +++ b/sflphone-common/src/audio/audioloop.h @@ -2,9 +2,9 @@ * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Yan Morin <yan.morin@savoirfairelinux.com> * - * Inspired by tonegenerator of + * Inspired by tonegenerator of * Laurielle Lea <laurielle.lea@savoirfairelinux.com> (2004) - * + * * 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 3 of the License, or @@ -41,60 +41,65 @@ * @brief Loop on a sound file */ -class AudioLoop { -public: - /** - * Constructor - */ - AudioLoop(); - - /** - * Virtual destructor - */ - virtual ~AudioLoop(); - - /** - * Get the next fragment of the tone - * the function change the intern position, and will loop - * @param output The data buffer - * @param nb of int16 to send - * @param volume The volume - * @return the number of int16 sent (nb*2) - */ - int getNext(SFLDataFormat* output, int nb, short volume=100); - - /** - * Reset the pointer position - */ - void reset() { _pos = 0; } - - /** - * Accessor to the size of the buffer - * @return unsigned int The size - */ - unsigned int getSize() { return _size; } - - -protected: - /** The data buffer */ - SFLDataFormat* _buffer; - - /** Number of int16 inside the buffer, not the delay */ - int _size; - - /** current position, set to 0, when initialize */ - int _pos; - - /** Sample rate */ - int _sampleRate; - -private: - - // Copy Constructor - AudioLoop(const AudioLoop& rh); - - // Assignment Operator - AudioLoop& operator=( const AudioLoop& rh); +class AudioLoop +{ + public: + /** + * Constructor + */ + AudioLoop(); + + /** + * Virtual destructor + */ + virtual ~AudioLoop(); + + /** + * Get the next fragment of the tone + * the function change the intern position, and will loop + * @param output The data buffer + * @param nb of int16 to send + * @param volume The volume + * @return the number of int16 sent (nb*2) + */ + int getNext (SFLDataFormat* output, int nb, short volume=100); + + /** + * Reset the pointer position + */ + void reset() { + _pos = 0; + } + + /** + * Accessor to the size of the buffer + * @return unsigned int The size + */ + unsigned int getSize() { + return _size; + } + + + protected: + /** The data buffer */ + SFLDataFormat* _buffer; + + /** Number of int16 inside the buffer, not the delay */ + int _size; + + /** current position, set to 0, when initialize */ + int _pos; + + /** Sample rate */ + int _sampleRate; + + private: + + // Copy Constructor + AudioLoop (const AudioLoop& rh); + + // Assignment Operator + AudioLoop& operator= (const AudioLoop& rh); }; #endif // __AUDIOLOOP_H__ diff --git a/sflphone-common/src/audio/audioprocessing.h b/sflphone-common/src/audio/audioprocessing.h index b69d6fc5058eef3611c602e3173703e196d1542c..a26078b5473f099d12d63c345904d055d797ba2b 100644 --- a/sflphone-common/src/audio/audioprocessing.h +++ b/sflphone-common/src/audio/audioprocessing.h @@ -35,59 +35,62 @@ #include "algorithm.h" /** - * Process audio buffers using specified at instantiation which may be + * Process audio buffers using specified at instantiation which may be * changed dynamically at runtime. */ -class AudioProcessing { +class AudioProcessing +{ -public: + public: - /** - * The constructor for this class - */ - AudioProcessing(Algorithm *_algo); + /** + * The constructor for this class + */ + AudioProcessing (Algorithm *_algo); - ~AudioProcessing(void); + ~AudioProcessing (void); - /** - * Set a new algorithm to process audio. Algorithm must be a subclass of abstract class Algorithm - */ - void setAlgorithm(Algorithm *_algo) { _algorithm = _algo; } + /** + * Set a new algorithm to process audio. Algorithm must be a subclass of abstract class Algorithm + */ + void setAlgorithm (Algorithm *_algo) { + _algorithm = _algo; + } - /** - * Reset parameters for the algorithm - */ - void resetAlgorithm(); + /** + * Reset parameters for the algorithm + */ + void resetAlgorithm(); - /** - * Put data in internal buffer - */ - void putData(SFLDataFormat *inputData, int nbBytes); + /** + * Put data in internal buffer + */ + void putData (SFLDataFormat *inputData, int nbBytes); - /** - * Get data from internal buffer - */ - int getData(SFLDataFormat *outputData); + /** + * Get data from internal buffer + */ + int getData (SFLDataFormat *outputData); - /** - * Process some audio data - */ - void processAudio(SFLDataFormat *inputData, int nbBytes); + /** + * Process some audio data + */ + void processAudio (SFLDataFormat *inputData, int nbBytes); - /** - * Process some audio data - */ - int processAudio(SFLDataFormat *inputData, SFLDataFormat *outputData, int nbBytes); + /** + * Process some audio data + */ + int processAudio (SFLDataFormat *inputData, SFLDataFormat *outputData, int nbBytes); - /** - * Process some audio data. - */ - void processAudio(SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes); + /** + * Process some audio data. + */ + void processAudio (SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes); -private: + private: - Algorithm *_algorithm; + Algorithm *_algorithm; }; diff --git a/sflphone-common/src/audio/audiorecord.cpp b/sflphone-common/src/audio/audiorecord.cpp index 977275e993c67f2ee345af9af0a87f0e6e31019f..88f9619edda47e702231141ef9289de679c3163f 100644 --- a/sflphone-common/src/audio/audiorecord.cpp +++ b/sflphone-common/src/audio/audiorecord.cpp @@ -49,21 +49,24 @@ struct wavhdr { }; -AudioRecord::AudioRecord() +AudioRecord::AudioRecord() : fp (NULL) + , channels_ (1) + , byteCounter_ (0) + , sndSmplRate_ (8000) + , nbSamplesMic_ (0) + , nbSamplesSpk_ (0) + , nbSamplesMax_ (3000) + , recordingEnabled_ (false) + , mixBuffer_ (NULL) + , micBuffer_ (NULL) + , spkBuffer_ (NULL) { - sndSmplRate_ = 8000; - channels_ = 1; - byteCounter_ = 0; - recordingEnabled_ = false; - fp = 0; - nbSamplesMax_ = 3000; - - createFilename(); - mixBuffer_ = new SFLDataFormat[nbSamplesMax_]; micBuffer_ = new SFLDataFormat[nbSamplesMax_]; spkBuffer_ = new SFLDataFormat[nbSamplesMax_]; + + createFilename(); } AudioRecord::~AudioRecord() @@ -82,7 +85,6 @@ void AudioRecord::setSndSamplingRate (int smplRate) void AudioRecord::setRecordingOption (FILE_TYPE type, SOUND_FORMAT format, int sndSmplRate, std::string path) { - fileType_ = type; sndFormat_ = format; channels_ = 1; @@ -299,6 +301,7 @@ bool AudioRecord::setRawFile() bool AudioRecord::setWavFile() { + _debug ("AudioRecord: Create wave file %s", savePath_.c_str()); fp = fopen (savePath_.c_str(), "wb"); @@ -496,7 +499,7 @@ void AudioRecord::recData (SFLDataFormat* buffer, int nSamples) } -void AudioRecord::recData (SFLDataFormat* buffer_1, SFLDataFormat* buffer_2, int nSamples_1, int nSamples_2) +void AudioRecord::recData (SFLDataFormat* buffer_1, SFLDataFormat* buffer_2, int nSamples_1, int nSamples_2 UNUSED) { if (recordingEnabled_) { diff --git a/sflphone-common/src/audio/audiorecord.h b/sflphone-common/src/audio/audiorecord.h index 8e42bd2a245f50c2874b8f313df28f98509510ce..f97401441ade6f6ead309c52b1ace4401d3a0a0e 100644 --- a/sflphone-common/src/audio/audiorecord.h +++ b/sflphone-common/src/audio/audiorecord.h @@ -45,196 +45,196 @@ typedef std::string CallID; class AudioRecord { -public: - - AudioRecord(); - - ~AudioRecord(); - - void setSndSamplingRate(int smplRate); - - void setRecordingOption(FILE_TYPE type, SOUND_FORMAT format, int sndSmplRate, std::string path); - - void initFileName( std::string peerNumber ); - - /** - * Check if no otehr file is opened, then create a new one - * @param fileName A string containing teh file (with/without extension) - * @param type The sound file format (FILE_RAW, FILE_WAVE) - * @param format Internal sound format (INT16 / INT32) - */ - void openFile(); - - /** - * Close the opend recording file. If wave: cout the number of byte - */ - void closeFile(); - - /** - * Check if a file is already opened - */ - bool isOpenFile(); - - /** - * Check if a file already exist - */ - bool isFileExist(); - - /** - * Check recording state - */ - bool isRecording(); - - /** - * Set recording flag - */ - bool setRecording(); - - /** - * Stop recording flag - */ - void stopRecording(); - - - /** - * Record a chunk of data in an internal buffer - * @param buffer The data chunk to be recorded - * @param nSamples Number of samples (number of bytes) to be recorded - */ - void recSpkrData(SFLDataFormat* buffer, int nSamples); - - /** - * Record a chunk of data in an internal buffer - * @param buffer The data chunk to be recorded - * @param nSamples Number of samples (number of bytes) to be recorded - */ - void recMicData(SFLDataFormat* buffer, int nSamples); - - /** - * Record a chunk of data in an openend file - * @param buffer The data chunk to be recorded - * @param nSamples Number of samples (number of bytes) to be recorded - */ - void recData(SFLDataFormat* buffer, int nSamples); - - /** - * Record a chunk of data in an openend file, Mix two differnet buffer - * @param buffer_1 The first data chunk to be recorded - * @param buffer_2 The second data chunk to be recorded - * @param nSamples_1 Number of samples (number of bytes) of buffer_1 - * @param nSamples_2 Number of samples (number of bytes) of buffer_2 - */ - void recData(SFLDataFormat* buffer_1, SFLDataFormat* buffer_2, int nSamples_1, int nSamples_2); - - -protected: - - /** - * Create name file according to current date - */ - void createFilename(); - - /** - * Set the header for raw files - */ - bool setRawFile(); - - /** - * Set the header for wave files - */ - bool setWavFile(); - - /** - * Open an existing raw file, used when the call is set on hold - */ - bool openExistingRawFile(); - - /** - * Open an existing wav file, used when the call is set on hold - */ - bool openExistingWavFile(); - - /** - * Compute the number of byte recorded and close the file - */ - void closeWavFile(); - - - /** - * Pointer to the recorded file - */ - FILE *fp; //file pointer - - /** - * File format (RAW / WAVE) - */ - FILE_TYPE fileType_; - - /** - * Sound format (SINT16/SINT32) - */ - SOUND_FORMAT sndFormat_; - - /** - * Number of channels - */ - int channels_; - - /** - * Number of byte recorded - */ - unsigned long byteCounter_; - - /** - * Sampling rate - */ - int sndSmplRate_; - - /** - * number of samples recorded for mic buffer - */ - int nbSamplesMic_; - - /** - * number of samples recorded for speaker buffer - */ - int nbSamplesSpk_; - - /** - * Maximum number of samples - */ - int nbSamplesMax_; - - /** - * Recording flage - */ - bool recordingEnabled_; - - /** - * Buffer used for mixing two channels - */ - SFLDataFormat* mixBuffer_; - - /** - * Buffer used to copy mic info - */ - SFLDataFormat* micBuffer_; - - /** - * Buffer used to copy spkr info - */ - SFLDataFormat* spkBuffer_; - - /** - * Filename for this recording - */ - char fileName_[8192]; - - /** - * Path for this recording - */ - std::string savePath_; - + public: + + AudioRecord(); + + ~AudioRecord(); + + void setSndSamplingRate (int smplRate); + + void setRecordingOption (FILE_TYPE type, SOUND_FORMAT format, int sndSmplRate, std::string path); + + void initFileName (std::string peerNumber); + + /** + * Check if no otehr file is opened, then create a new one + * @param fileName A string containing teh file (with/without extension) + * @param type The sound file format (FILE_RAW, FILE_WAVE) + * @param format Internal sound format (INT16 / INT32) + */ + void openFile(); + + /** + * Close the opend recording file. If wave: cout the number of byte + */ + void closeFile(); + + /** + * Check if a file is already opened + */ + bool isOpenFile(); + + /** + * Check if a file already exist + */ + bool isFileExist(); + + /** + * Check recording state + */ + bool isRecording(); + + /** + * Set recording flag + */ + bool setRecording(); + + /** + * Stop recording flag + */ + void stopRecording(); + + + /** + * Record a chunk of data in an internal buffer + * @param buffer The data chunk to be recorded + * @param nSamples Number of samples (number of bytes) to be recorded + */ + void recSpkrData (SFLDataFormat* buffer, int nSamples); + + /** + * Record a chunk of data in an internal buffer + * @param buffer The data chunk to be recorded + * @param nSamples Number of samples (number of bytes) to be recorded + */ + void recMicData (SFLDataFormat* buffer, int nSamples); + + /** + * Record a chunk of data in an openend file + * @param buffer The data chunk to be recorded + * @param nSamples Number of samples (number of bytes) to be recorded + */ + void recData (SFLDataFormat* buffer, int nSamples); + + /** + * Record a chunk of data in an openend file, Mix two differnet buffer + * @param buffer_1 The first data chunk to be recorded + * @param buffer_2 The second data chunk to be recorded + * @param nSamples_1 Number of samples (number of bytes) of buffer_1 + * @param nSamples_2 Number of samples (number of bytes) of buffer_2 + */ + void recData (SFLDataFormat* buffer_1, SFLDataFormat* buffer_2, int nSamples_1, int nSamples_2); + + + protected: + + /** + * Create name file according to current date + */ + void createFilename(); + + /** + * Set the header for raw files + */ + bool setRawFile(); + + /** + * Set the header for wave files + */ + bool setWavFile(); + + /** + * Open an existing raw file, used when the call is set on hold + */ + bool openExistingRawFile(); + + /** + * Open an existing wav file, used when the call is set on hold + */ + bool openExistingWavFile(); + + /** + * Compute the number of byte recorded and close the file + */ + void closeWavFile(); + + + /** + * Pointer to the recorded file + */ + FILE *fp; //file pointer + + /** + * File format (RAW / WAVE) + */ + FILE_TYPE fileType_; + + /** + * Sound format (SINT16/SINT32) + */ + SOUND_FORMAT sndFormat_; + + /** + * Number of channels + */ + int channels_; + + /** + * Number of byte recorded + */ + unsigned long byteCounter_; + + /** + * Sampling rate + */ + int sndSmplRate_; + + /** + * number of samples recorded for mic buffer + */ + int nbSamplesMic_; + + /** + * number of samples recorded for speaker buffer + */ + int nbSamplesSpk_; + + /** + * Maximum number of samples + */ + int nbSamplesMax_; + + /** + * Recording flage + */ + bool recordingEnabled_; + + /** + * Buffer used for mixing two channels + */ + SFLDataFormat* mixBuffer_; + + /** + * Buffer used to copy mic info + */ + SFLDataFormat* micBuffer_; + + /** + * Buffer used to copy spkr info + */ + SFLDataFormat* spkBuffer_; + + /** + * Filename for this recording + */ + char fileName_[8192]; + + /** + * Path for this recording + */ + std::string savePath_; + }; #endif // _AUDIO_RECORD_H diff --git a/sflphone-common/src/audio/audiorecorder.cpp b/sflphone-common/src/audio/audiorecorder.cpp index 559c4f0f34d2657b8ffbf14b4e8a92ba62b3e043..0adba9caa09b323fb17bfc37cec34ad17baf3552 100644 --- a/sflphone-common/src/audio/audiorecorder.cpp +++ b/sflphone-common/src/audio/audiorecorder.cpp @@ -59,7 +59,9 @@ AudioRecorder::AudioRecorder (AudioRecord *arec, MainBuffer *mb) : Thread() */ void AudioRecorder::run (void) { - SFLDataFormat buffer[10000]; + + int bufferLength = 10000; + SFLDataFormat buffer[bufferLength]; while (true) { @@ -68,11 +70,11 @@ void AudioRecorder::run (void) int availBytes = mbuffer->availForGet (recorderId); - if (availBytes > 0) { + int toGet = (availBytes < bufferLength) ? availBytes : bufferLength; - int got = mbuffer->getData (buffer, availBytes, 100, recorderId); + mbuffer->getData (buffer, toGet, 100, recorderId); - int availBytesAfter = mbuffer->availForGet (recorderId); + if (availBytes > 0) { arecord->recData (buffer, availBytes/sizeof (SFLDataFormat)); } diff --git a/sflphone-common/src/audio/audiorecorder.h b/sflphone-common/src/audio/audiorecorder.h index b1c15f3a489a49fa058b320cb81caa8153e93208..66e79d4bc54cfaa155a5c1aba3439c1396364a7a 100644 --- a/sflphone-common/src/audio/audiorecorder.h +++ b/sflphone-common/src/audio/audiorecorder.h @@ -1,17 +1,17 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Alexandre Savard <alexandre.savard@savoirfairelinux.com> - * + * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -37,28 +37,33 @@ class MainBuffer; -class AudioRecorder : public ost::Thread { +class AudioRecorder : public ost::Thread +{ - public: - AudioRecorder(AudioRecord *arec, MainBuffer *mb); + public: + AudioRecorder (AudioRecord *arec, MainBuffer *mb); - ~AudioRecorder(void){ terminate(); } + ~AudioRecorder (void) { + terminate(); + } - static int count; + static int count; - std::string getRecorderID() { return recorderId; } + std::string getRecorderID() { + return recorderId; + } - virtual void run(); + virtual void run(); - private: - AudioRecorder (const AudioRecorder& ar); - AudioRecorder& operator=(const AudioRecorder& ar); + private: + AudioRecorder (const AudioRecorder& ar); + AudioRecorder& operator= (const AudioRecorder& ar); - std::string recorderId; + std::string recorderId; - MainBuffer *mbuffer; + MainBuffer *mbuffer; - AudioRecord *arecord; + AudioRecord *arecord; }; #endif diff --git a/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp b/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp index 76884ef124cb5fb627218eabdaf89ea29847d0de..eabf054b16c08dd13c6cb93672fa118e8ac11452 100644 --- a/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp +++ b/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp @@ -36,6 +36,7 @@ #include "manager.h" #include "account.h" #include "sip/sipcall.h" +#include "sip/sipaccount.h" #include "sip/SdesNegotiator.h" #include <assert.h> @@ -76,28 +77,44 @@ void AudioRtpFactory::initAudioRtpConfig (SIPCall *ca) AccountID accountId = Manager::instance().getAccountFromCall (ca->getCallId()); - // Check if it is an IP-to-IP call - if (accountId == AccountNULL) { - _srtpEnabled = Manager::instance().getConfigBool (IP2IP_PROFILE, SRTP_ENABLE); - _keyExchangeProtocol = Manager::instance().getConfigInt (IP2IP_PROFILE, SRTP_KEY_EXCHANGE); - _debug ("Ip-to-ip profile selected with key exchange protocol number %d", _keyExchangeProtocol); - _helloHashEnabled = Manager::instance().getConfigBool (IP2IP_PROFILE, ZRTP_HELLO_HASH); - } else { - _srtpEnabled = Manager::instance().getConfigBool (accountId, SRTP_ENABLE); - _keyExchangeProtocol = Manager::instance().getConfigInt (accountId, SRTP_KEY_EXCHANGE); + _debug ("AudioRtpFactory: Init rtp session for account %s", accountId.c_str()); + + // Manager::instance().getAccountLink (accountId); + Account *account = Manager::instance().getAccount (accountId); + + if (!account) + _error ("AudioRtpFactory: Error no account found"); + + if (account->getType() == "SIP") { + SIPAccount *sipaccount = static_cast<SIPAccount *> (account); + _srtpEnabled = sipaccount->getSrtpEnable(); + std::string tempkey = sipaccount->getSrtpKeyExchange(); + + if (tempkey == "sdes") + _keyExchangeProtocol = Sdes; + else if (tempkey == "zrtp") + _keyExchangeProtocol = Zrtp; + else + _keyExchangeProtocol = Symmetric; + _debug ("Registered account %s profile selected with key exchange protocol number %d", accountId.c_str(), _keyExchangeProtocol); - _helloHashEnabled = Manager::instance().getConfigBool (accountId, ZRTP_HELLO_HASH); + _helloHashEnabled = sipaccount->getZrtpHelloHash(); + } else { + _srtpEnabled = false; + _keyExchangeProtocol = Symmetric; + _helloHashEnabled = false; } + } void AudioRtpFactory::initAudioRtpSession (SIPCall * ca) { ost::MutexLock m (_audioRtpThreadMutex); - _debug ("Srtp enable: %d ", _srtpEnabled); + _debug ("AudioRtpFactory: Srtp enable: %d ", _srtpEnabled); if (_srtpEnabled) { - std::string zidFilename (Manager::instance().getConfigString (SIGNALISATION, ZRTP_ZIDFILE)); + std::string zidFilename (Manager::instance().voipPreferences.getZidFile()); switch (_keyExchangeProtocol) { diff --git a/sflphone-common/src/audio/audiortp/AudioRtpFactory.h b/sflphone-common/src/audio/audiortp/AudioRtpFactory.h index 74de2364b94a16cf169aeadda853ec98ebc4becf..b870333fb055a655aa842e8cd1c833511b6a6d70 100644 --- a/sflphone-common/src/audio/audiortp/AudioRtpFactory.h +++ b/sflphone-common/src/audio/audiortp/AudioRtpFactory.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com> - * + * * 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 3 of the License, or @@ -10,7 +10,7 @@ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -39,146 +39,163 @@ class SdesNegotiator; class SIPCall; -namespace sfl { - class AudioZrtpSession; - class AudioSrtpSession; - class AudioSymmetricRtpSession; +namespace sfl +{ +class AudioZrtpSession; +class AudioSrtpSession; +class AudioSymmetricRtpSession; } -namespace sfl { +namespace sfl +{ - class AudioZrtpSession; - class AudioSrtpSession; +class AudioZrtpSession; +class AudioSrtpSession; - // Possible kind of rtp session - typedef enum RtpMethod { - Symmetric, - Zrtp, - Sdes - } RtpMethod; +// Possible kind of rtp session +typedef enum RtpMethod { + Symmetric, + Zrtp, + Sdes +} RtpMethod; - class UnsupportedRtpSessionType : public std::logic_error { - public: - UnsupportedRtpSessionType(const std::string& msg = "") : std::logic_error(msg) {} - }; - - class AudioRtpFactoryException : public std::logic_error { - public: - AudioRtpFactoryException(const std::string& msg = "") : std::logic_error(msg) {} - }; +class UnsupportedRtpSessionType : public std::logic_error +{ + public: + UnsupportedRtpSessionType (const std::string& msg = "") : std::logic_error (msg) {} +}; + +class AudioRtpFactoryException : public std::logic_error +{ + public: + AudioRtpFactoryException (const std::string& msg = "") : std::logic_error (msg) {} +}; - class AudioRtpFactory { - public: +class AudioRtpFactory +{ + public: AudioRtpFactory(); - AudioRtpFactory(SIPCall * ca); + AudioRtpFactory (SIPCall * ca); ~AudioRtpFactory(); - void initAudioRtpConfig(SIPCall *ca); - - /** - * Lazy instantiation method. Create a new RTP session of a given - * type according to the content of the configuration file. - * @param ca A pointer on a SIP call - * @return A new AudioRtpSession object - */ - void initAudioRtpSession(SIPCall *ca); - - /** - * Start the audio rtp thread of the type specified in the configuration - * file. initAudioRtpSession must have been called prior to that. - * @param None - */ - void start(AudioCodec*); - - /** - * Stop the audio rtp thread of the type specified in the configuration - * file. initAudioRtpSession must have been called prior to that. - * @param None - */ - void stop(); - - /** - * Update current RTP destination address with one stored in call - * @param None - */ - void updateDestinationIpAddress (void); - - /** - * @param None - * @return The internal audio rtp thread of the type specified in the configuration - * file. initAudioRtpSession must have been called prior to that. - */ - inline void * getAudioRtpSession(void) { return _rtpSession; } - - AudioSymmetricRtpSession * getAudioSymetricRtpSession(); - - /** - * @param None - * @return The internal audio rtp session type - * Symmetric = 0 - * Zrtp = 1 - * Sdes = 2 - */ - inline RtpMethod getAudioRtpType(void) { return _rtpSessionType; } - - /** - * @param Set internal audio rtp session type (Symmetric, Zrtp, Sdes) - */ - inline void setAudioRtpType(RtpMethod type) { _rtpSessionType = type; } - - /** - * Manually set the srtpEnable option (usefull for RTP fallback) - */ - void setSrtpEnabled(bool enable){ _srtpEnabled = enable; } - - /** - * Manually set the keyExchangeProtocol parameter (usefull for RTP fallback) - */ - void setKeyExchangeProtocol(int proto){ _keyExchangeProtocol = proto; } - - /** - * Manually set the setHelloHashEnabled parameter (usefull for RTP fallback) - */ - void setHelloHashEnabled(bool enable){ _helloHashEnabled = enable; } - - /** - * Get the current AudioZrtpSession. Throws an AudioRtpFactoryException - * if the current rtp thread is null, or if it's not of the correct type. - * @return The current AudioZrtpSession thread. - */ - sfl::AudioZrtpSession * getAudioZrtpSession(); - - /** - * Set remote cryptographic info. Should be called after negotiation in SDP - * offer/answer session. - */ - void setRemoteCryptoInfo(sfl::SdesNegotiator& nego); - - /** - * Send DTMF over RTP (RFC2833). The timestamp and sequence number must be - * incremented as if it was microphone audio. This function change the payload type of the rtp session, - * send the appropriate DTMF digit using this payload, discard coresponding data from mainbuffer and get - * back the codec payload for further audio processing. - */ - void sendDtmfDigit(int digit); - -private: - void * _rtpSession; - RtpMethod _rtpSessionType; - ost::Mutex _audioRtpThreadMutex; - - // Field used when initializinga udio rtp session - // May be set manually or from config using initAudioRtpConfig - bool _srtpEnabled; - - // Field used when initializinga udio rtp session - // May be set manually or from config using initAudioRtpConfig - int _keyExchangeProtocol; - - // Field used when initializinga udio rtp session - // May be set manually or from config using initAudioRtpConfig - bool _helloHashEnabled; + void initAudioRtpConfig (SIPCall *ca); + + /** + * Lazy instantiation method. Create a new RTP session of a given + * type according to the content of the configuration file. + * @param ca A pointer on a SIP call + * @return A new AudioRtpSession object + */ + void initAudioRtpSession (SIPCall *ca); + + /** + * Start the audio rtp thread of the type specified in the configuration + * file. initAudioRtpSession must have been called prior to that. + * @param None + */ + void start (AudioCodec*); + + /** + * Stop the audio rtp thread of the type specified in the configuration + * file. initAudioRtpSession must have been called prior to that. + * @param None + */ + void stop(); + + /** + * Update current RTP destination address with one stored in call + * @param None + */ + void updateDestinationIpAddress (void); + + /** + * @param None + * @return The internal audio rtp thread of the type specified in the configuration + * file. initAudioRtpSession must have been called prior to that. + */ + inline void * getAudioRtpSession (void) { + return _rtpSession; + } + + AudioSymmetricRtpSession * getAudioSymetricRtpSession(); + + /** + * @param None + * @return The internal audio rtp session type + * Symmetric = 0 + * Zrtp = 1 + * Sdes = 2 + */ + inline RtpMethod getAudioRtpType (void) { + return _rtpSessionType; + } + + /** + * @param Set internal audio rtp session type (Symmetric, Zrtp, Sdes) + */ + inline void setAudioRtpType (RtpMethod type) { + _rtpSessionType = type; + } + + /** + * Manually set the srtpEnable option (usefull for RTP fallback) + */ + void setSrtpEnabled (bool enable) { + _srtpEnabled = enable; + } + + /** + * Manually set the keyExchangeProtocol parameter (usefull for RTP fallback) + */ + void setKeyExchangeProtocol (int proto) { + _keyExchangeProtocol = proto; + } + + /** + * Manually set the setHelloHashEnabled parameter (usefull for RTP fallback) + */ + void setHelloHashEnabled (bool enable) { + _helloHashEnabled = enable; + } + + /** + * Get the current AudioZrtpSession. Throws an AudioRtpFactoryException + * if the current rtp thread is null, or if it's not of the correct type. + * @return The current AudioZrtpSession thread. + */ + sfl::AudioZrtpSession * getAudioZrtpSession(); + + /** + * Set remote cryptographic info. Should be called after negotiation in SDP + * offer/answer session. + */ + void setRemoteCryptoInfo (sfl::SdesNegotiator& nego); + + /** + * Send DTMF over RTP (RFC2833). The timestamp and sequence number must be + * incremented as if it was microphone audio. This function change the payload type of the rtp session, + * send the appropriate DTMF digit using this payload, discard coresponding data from mainbuffer and get + * back the codec payload for further audio processing. + */ + void sendDtmfDigit (int digit); + + private: + void * _rtpSession; + RtpMethod _rtpSessionType; + ost::Mutex _audioRtpThreadMutex; + + // Field used when initializinga udio rtp session + // May be set manually or from config using initAudioRtpConfig + bool _srtpEnabled; + + // Field used when initializinga udio rtp session + // May be set manually or from config using initAudioRtpConfig + int _keyExchangeProtocol; + + // Field used when initializinga udio rtp session + // May be set manually or from config using initAudioRtpConfig + bool _helloHashEnabled; }; } #endif // __AUDIO_RTP_FACTORY_H__ diff --git a/sflphone-common/src/audio/audiortp/AudioRtpSession.h b/sflphone-common/src/audio/audiortp/AudioRtpSession.h index 5144d3767989d019316a1837aaaa0c0c2f189e3b..5db39baf38adda0e91c9dde019b97eb6f79f66fc 100644 --- a/sflphone-common/src/audio/audiortp/AudioRtpSession.h +++ b/sflphone-common/src/audio/audiortp/AudioRtpSession.h @@ -15,7 +15,7 @@ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -57,786 +57,807 @@ // Frequency (in packet number) #define RTP_TIMESTAMP_RESET_FREQ 100 -namespace sfl { - - static const int schedulingTimeout = 100000; - static const int expireTimeout = 1000000; - - - class AudioRtpSessionException: public std::exception - { - virtual const char* what() const throw() - { - return "AudioRtpSessionException occured"; - } - }; - - typedef struct DtmfEvent { - ost::RTPPacket::RFC2833Payload payload; - int length; - bool newevent; - } DtmfEvent; - - typedef list<DtmfEvent *> EventQueue; - - template <typename D> - class AudioRtpSession : public ost::Thread, public ost::TimerPort { - public: - /** - * Constructor - * @param sipcall The pointer on the SIP call - */ - AudioRtpSession (ManagerImpl * manager, SIPCall* sipcall); - - ~AudioRtpSession(); - - // Thread associated method - virtual void run (); - - int startRtpThread(AudioCodec*); - - /** - * Used mostly when receiving a reinvite - */ - void updateDestinationIpAddress(void); - - void putDtmfEvent(int digit); - - /** - * Send DTMF over RTP (RFC2833). The timestamp and sequence number must be - * incremented as if it was microphone audio. This function change the payload type of the rtp session, - * send the appropriate DTMF digit using this payload, discard coresponding data from mainbuffer and get - * back the codec payload for further audio processing. - */ - void sendDtmfEvent(sfl::DtmfEvent *dtmf); - - inline float computeCodecFrameSize (int codecSamplePerFrame, int codecClockRate) { - return ( (float) codecSamplePerFrame * 1000.0) / (float) codecClockRate; - } +namespace sfl +{ - int computeNbByteAudioLayer (float codecFrameSize) { - return (int) ( ((float) _converterSamplingRate * codecFrameSize * sizeof(SFLDataFormat))/ 1000.0); - } +static const int schedulingTimeout = 100000; +static const int expireTimeout = 1000000; - private: - - void initBuffers(void); - - void setSessionTimeouts(void); - void setSessionMedia(AudioCodec*); - void setDestinationIpAddress(void); - - int processDataEncode(void); - void processDataDecode(unsigned char * spkrData, unsigned int size); - - void sendMicData(); - void receiveSpeakerData (); - - ost::Time * _time; - - // This semaphore is not used - // but is needed in order to avoid - // ambiguous compiling problem. - // It is set to 0, and since it is - // optional in ost::thread, then - // it amounts to the same as doing - // start() with no semaphore at all. - ost::Semaphore * _mainloopSemaphore; - - // Main destination address for this rtp session. - // Stored in case or reINVITE, which may require to forget - // this destination and update a new one. - ost::InetHostAddress _remote_ip; - - - // Main destination port for this rtp session. - // Stored in case reINVITE, which may require to forget - // this destination and update a new one - unsigned short _remote_port; - - AudioCodec * _audiocodec; - - AudioLayer * _audiolayer; - - /** Mic-data related buffers */ - SFLDataFormat* _micData; - SFLDataFormat* _micDataConverted; - unsigned char* _micDataEncoded; - - /** Speaker-data related buffers */ - SFLDataFormat* _spkrDataDecoded; - SFLDataFormat* _spkrDataConverted; - - /** Sample rate converter object */ - SamplerateConverter * _converter; - - /** Variables to process audio stream: sample rate for playing sound (typically 44100HZ) */ - int _layerSampleRate; - - /** Sample rate of the codec we use to encode and decode (most of time 8000HZ) */ - int _codecSampleRate; - - /** Length of the sound frame we capture in ms (typically 20ms) */ - int _layerFrameSize; - - /** Codecs frame size in samples (20 ms => 882 at 44.1kHz) - The exact value is stored in the codec */ - int _codecFrameSize; - - /** Speaker buffer length in samples once the data are resampled - * (used for mixing and recording) - */ - int _nSamplesSpkr; - - /** Mic buffer length in samples once the data are resampled - * (used for mixing and recording) - */ - int _nSamplesMic; - - /** - * Maximum number of sample for audio buffers (mic and spkr) - */ - int _nbSamplesMax; - - /** - * Manager instance. - */ - ManagerImpl * _manager; - - /** - * Sampling rate of audio converter - */ - int _converterSamplingRate; - - /** - * Timestamp for this session - */ - int _timestamp; - - /** - * Timestamp incrementation value based on codec period length (framesize) - * except for G722 which require a 8 kHz incrementation. - */ - int _timestampIncrement; - - /** - * Timestamp reset freqeuncy specified in number of packet sent - */ - short _timestampCount; - - /** - * Time counter used to trigger incoming call notification - */ - int _countNotificationTime; - - /** - * EventQueue used to store list of DTMF- - */ - EventQueue _eventQueue; - - /** - * Adaptive jitter buffer - */ - jitterbuf * _jbuffer; - - /** - * Packet size in ms - */ - int _packetLength; - - int _ts; - - /** - * Current time in ms - */ - int _currentTime; - - SpeexPreprocessState *_noiseState; - - protected: - - SIPCall * _ca; - - bool onRTPPacketRecv(ost::IncomingRTPPkt&); - }; - - template <typename D> - AudioRtpSession<D>::AudioRtpSession(ManagerImpl * manager, SIPCall * sipcall) : - _time (new ost::Time()), - _mainloopSemaphore(0), - _audiocodec (NULL), - _audiolayer (NULL), - _micData (NULL), - _micDataConverted (NULL), - _micDataEncoded (NULL), - _spkrDataDecoded (NULL), - _spkrDataConverted (NULL), - _converter (NULL), - _layerSampleRate(0), - _codecSampleRate(0), - _layerFrameSize(0), - _manager(manager), - _converterSamplingRate(0), - _timestamp(0), - _timestampIncrement(0), - _timestampCount(0), - _countNotificationTime(0), - _jbuffer(NULL), - _noiseState(NULL), - _ca (sipcall) - { - setCancel (cancelDefault); - - assert(_ca); - - _info ("Rtp: Local audio port %i will be used", _ca->getLocalAudioPort()); - - //mic, we receive from soundcard in stereo, and we send encoded - _audiolayer = _manager->getAudioDriver(); - - if (_audiolayer == NULL) { throw AudioRtpSessionException(); } - - _layerFrameSize = _audiolayer->getFrameSize(); // in ms - _layerSampleRate = _audiolayer->getSampleRate(); - - _jbuffer = jb_new(); - - _jbuffer->info.conf.max_jitterbuf = 1000; - _jbuffer->info.conf.target_extra = 100; - _jbuffer->info.silence_begin_ts = 0; - - _ts= 0; - _packetLength = 20; - _currentTime = 0; - } - - template <typename D> - AudioRtpSession<D>::~AudioRtpSession() - { - _debug ("RTP: Delete AudioRtpSession instance"); - - try { - terminate(); - } catch (...) { - _debugException ("Thread destructor didn't terminate correctly"); - throw; + +class AudioRtpSessionException: public std::exception +{ + virtual const char* what() const throw() { + return "AudioRtpSessionException occured"; } +}; + +typedef struct DtmfEvent { + ost::RTPPacket::RFC2833Payload payload; + int length; + bool newevent; +} DtmfEvent; + +typedef list<DtmfEvent *> EventQueue; + +template <typename D> +class AudioRtpSession : public ost::Thread, public ost::TimerPort +{ + public: + /** + * Constructor + * @param sipcall The pointer on the SIP call + */ + AudioRtpSession (ManagerImpl * manager, SIPCall* sipcall); + + ~AudioRtpSession(); + + // Thread associated method + virtual void run (); + + int startRtpThread (AudioCodec*); + + /** + * Used mostly when receiving a reinvite + */ + void updateDestinationIpAddress (void); + + void putDtmfEvent (int digit); + + /** + * Send DTMF over RTP (RFC2833). The timestamp and sequence number must be + * incremented as if it was microphone audio. This function change the payload type of the rtp session, + * send the appropriate DTMF digit using this payload, discard coresponding data from mainbuffer and get + * back the codec payload for further audio processing. + */ + void sendDtmfEvent (sfl::DtmfEvent *dtmf); + + inline float computeCodecFrameSize (int codecSamplePerFrame, int codecClockRate) { + return ( (float) codecSamplePerFrame * 1000.0) / (float) codecClockRate; + } + + int computeNbByteAudioLayer (float codecFrameSize) { + return (int) ( ( (float) _converterSamplingRate * codecFrameSize * sizeof (SFLDataFormat)) / 1000.0); + } + + private: + + void initBuffers (void); + + void setSessionTimeouts (void); + void setSessionMedia (AudioCodec*); + void setDestinationIpAddress (void); + + int processDataEncode (void); + void processDataDecode (unsigned char * spkrData, unsigned int size); + + void sendMicData(); + void receiveSpeakerData (); + + ost::Time * _time; + + // This semaphore is not used + // but is needed in order to avoid + // ambiguous compiling problem. + // It is set to 0, and since it is + // optional in ost::thread, then + // it amounts to the same as doing + // start() with no semaphore at all. + ost::Semaphore * _mainloopSemaphore; + + // Main destination address for this rtp session. + // Stored in case or reINVITE, which may require to forget + // this destination and update a new one. + ost::InetHostAddress _remote_ip; + + + // Main destination port for this rtp session. + // Stored in case reINVITE, which may require to forget + // this destination and update a new one + unsigned short _remote_port; - _manager->getAudioDriver()->getMainBuffer()->unBindAll(_ca->getCallId()); + AudioCodec * _audiocodec; + AudioLayer * _audiolayer; + + /** Mic-data related buffers */ + SFLDataFormat* _micData; + SFLDataFormat* _micDataConverted; + unsigned char* _micDataEncoded; + + /** Speaker-data related buffers */ + SFLDataFormat* _spkrDataDecoded; + SFLDataFormat* _spkrDataConverted; + + /** Sample rate converter object */ + SamplerateConverter * _converter; + + /** Variables to process audio stream: sample rate for playing sound (typically 44100HZ) */ + int _layerSampleRate; + + /** Sample rate of the codec we use to encode and decode (most of time 8000HZ) */ + int _codecSampleRate; + + /** Length of the sound frame we capture in ms (typically 20ms) */ + int _layerFrameSize; + + /** Codecs frame size in samples (20 ms => 882 at 44.1kHz) + The exact value is stored in the codec */ + int _codecFrameSize; + + /** Speaker buffer length in samples once the data are resampled + * (used for mixing and recording) + */ + int _nSamplesSpkr; + + /** Mic buffer length in samples once the data are resampled + * (used for mixing and recording) + */ + int _nSamplesMic; + + /** + * Maximum number of sample for audio buffers (mic and spkr) + */ + int _nbSamplesMax; + + /** + * Manager instance. + */ + ManagerImpl * _manager; + + /** + * Sampling rate of audio converter + */ + int _converterSamplingRate; + + /** + * Timestamp for this session + */ + int _timestamp; + + /** + * Timestamp incrementation value based on codec period length (framesize) + * except for G722 which require a 8 kHz incrementation. + */ + int _timestampIncrement; + + /** + * Timestamp reset freqeuncy specified in number of packet sent + */ + short _timestampCount; + + /** + * Time counter used to trigger incoming call notification + */ + int _countNotificationTime; + + /** + * EventQueue used to store list of DTMF- + */ + EventQueue _eventQueue; + + /** + * Adaptive jitter buffer + */ + jitterbuf * _jbuffer; + + /** + * Packet size in ms + */ + int _packetLength; + + int _ts; + + /** + * Current time in ms + */ + int _currentTime; + + SpeexPreprocessState *_noiseState; + + protected: + + SIPCall * _ca; + + bool onRTPPacketRecv (ost::IncomingRTPPkt&); +}; + +template <typename D> +AudioRtpSession<D>::AudioRtpSession (ManagerImpl * manager, SIPCall * sipcall) : + _time (new ost::Time()), + _mainloopSemaphore (0), + _audiocodec (NULL), + _audiolayer (NULL), + _micData (NULL), + _micDataConverted (NULL), + _micDataEncoded (NULL), + _spkrDataDecoded (NULL), + _spkrDataConverted (NULL), + _converter (NULL), + _layerSampleRate (0), + _codecSampleRate (0), + _layerFrameSize (0), + _manager (manager), + _converterSamplingRate (0), + _timestamp (0), + _timestampIncrement (0), + _timestampCount (0), + _countNotificationTime (0), + _jbuffer (NULL), + _noiseState (NULL), + _ca (sipcall) +{ + setCancel (cancelDefault); + + assert (_ca); + + _info ("Rtp: Local audio port %i will be used", _ca->getLocalAudioPort()); + + //mic, we receive from soundcard in stereo, and we send encoded + _audiolayer = _manager->getAudioDriver(); + + if (_audiolayer == NULL) { + throw AudioRtpSessionException(); + } + + _layerFrameSize = _audiolayer->getFrameSize(); // in ms + _layerSampleRate = _audiolayer->getSampleRate(); + + _jbuffer = jb_new(); + + _jbuffer->info.conf.max_jitterbuf = 1000; + _jbuffer->info.conf.target_extra = 100; + _jbuffer->info.silence_begin_ts = 0; + + _ts= 0; + _packetLength = 20; + _currentTime = 0; +} + +template <typename D> +AudioRtpSession<D>::~AudioRtpSession() +{ + _debug ("RTP: Delete AudioRtpSession instance"); + + try { + terminate(); + } catch (...) { + _debugException ("Thread destructor didn't terminate correctly"); + throw; + } + + _manager->getAudioDriver()->getMainBuffer()->unBindAll (_ca->getCallId()); + + if (_micData) { delete [] _micData; + _micData = NULL; + } + + if (_micDataConverted) { delete [] _micDataConverted; + _micDataConverted = NULL; + } + + if (_micDataEncoded) { delete [] _micDataEncoded; + _micDataEncoded = NULL; + } + + if (_spkrDataDecoded) { delete [] _spkrDataDecoded; + _spkrDataDecoded = NULL; + } + + if (_spkrDataConverted) { delete [] _spkrDataConverted; - delete _time; - delete _converter; + _spkrDataConverted = NULL; + } - if (_audiocodec) { - delete _audiocodec; _audiocodec = NULL; - } + delete _time; + delete _converter; - if(_jbuffer) { - jb_destroy(_jbuffer); - } + if (_audiocodec) { + delete _audiocodec; + _audiocodec = NULL; + } - if(_noiseState) { - speex_preprocess_state_destroy(_noiseState); - } - + if (_jbuffer) { + jb_destroy (_jbuffer); } - - template <typename D> - void AudioRtpSession<D>::initBuffers() - { - // Set sampling rate, main buffer choose the highest one - _manager->getAudioDriver()->getMainBuffer()->setInternalSamplingRate(_codecSampleRate); - - // may be different than one already setted - _converterSamplingRate = _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate(); - // initialize SampleRate converter using AudioLayer's sampling rate - // (internal buffers initialized with maximal sampling rate and frame size) - _converter = new SamplerateConverter(_layerSampleRate, _layerFrameSize); + if (_noiseState) { + speex_preprocess_state_destroy (_noiseState); + } + +} + +template <typename D> +void AudioRtpSession<D>::initBuffers() +{ + // Set sampling rate, main buffer choose the highest one + _manager->getAudioDriver()->getMainBuffer()->setInternalSamplingRate (_codecSampleRate); + + // may be different than one already setted + _converterSamplingRate = _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate(); + + // initialize SampleRate converter using AudioLayer's sampling rate + // (internal buffers initialized with maximal sampling rate and frame size) + _converter = new SamplerateConverter (_layerSampleRate, _layerFrameSize); + + int nbSamplesMax = (int) (_codecSampleRate * _layerFrameSize /1000) *2; + _micData = new SFLDataFormat[nbSamplesMax]; + _micDataConverted = new SFLDataFormat[nbSamplesMax]; + _micDataEncoded = new unsigned char[nbSamplesMax]; + _spkrDataConverted = new SFLDataFormat[nbSamplesMax]; + _spkrDataDecoded = new SFLDataFormat[nbSamplesMax]; - int nbSamplesMax = (int)(_codecSampleRate * _layerFrameSize /1000)*2; - _micData = new SFLDataFormat[nbSamplesMax]; - _micDataConverted = new SFLDataFormat[nbSamplesMax]; - _micDataEncoded = new unsigned char[nbSamplesMax]; - _spkrDataConverted = new SFLDataFormat[nbSamplesMax]; - _spkrDataDecoded = new SFLDataFormat[nbSamplesMax]; - _manager->addStream(_ca->getCallId()); + memset (_micData, 0, nbSamplesMax); + memset (_micDataConverted, 0, nbSamplesMax); + memset (_micDataEncoded, 0, nbSamplesMax); + memset (_spkrDataConverted, 0, nbSamplesMax); + memset (_spkrDataDecoded, 0, nbSamplesMax); + + _manager->addStream (_ca->getCallId()); +} + +template <typename D> +void AudioRtpSession<D>::setSessionTimeouts (void) +{ + try { + static_cast<D*> (this)->setSchedulingTimeout (schedulingTimeout); + static_cast<D*> (this)->setExpireTimeout (expireTimeout); + } catch (...) { + _debugException ("Initialization failed while setting timeouts"); + throw AudioRtpSessionException(); } - - template <typename D> - void AudioRtpSession<D>::setSessionTimeouts(void) - { - try { - static_cast<D*>(this)->setSchedulingTimeout (schedulingTimeout); - static_cast<D*>(this)->setExpireTimeout (expireTimeout); - } catch (...) { - _debugException ("Initialization failed while setting timeouts"); - throw AudioRtpSessionException(); - } +} + +template <typename D> +void AudioRtpSession<D>::setSessionMedia (AudioCodec* audiocodec) +{ + _audiocodec = audiocodec; + + _debug ("RTP: Init codec payload %i", _audiocodec->getPayload()); + + _codecSampleRate = _audiocodec->getClockRate(); + _codecFrameSize = _audiocodec->getFrameSize(); + + // G722 requires timestamp to be incremented at 8 kHz + if (_audiocodec->getPayload() == 9) + _timestampIncrement = 160; + else + _timestampIncrement = _codecFrameSize; + + + _debug ("RTP: Codec sampling rate: %d", _codecSampleRate); + _debug ("RTP: Codec frame size: %d", _codecFrameSize); + _debug ("RTP: RTP timestamp increment: %d", _timestampIncrement); + + // Even if specified as a 16 kHz codec, G722 requires rtp sending rate to be 8 kHz + if (_audiocodec->getPayload() == 9) { + _debug ("RTP: Setting G722 payload format"); + static_cast<D*> (this)->setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) _audiocodec->getPayload(), _audiocodec->getClockRate())); + } else if (_audiocodec->hasDynamicPayload()) { + _debug ("RTP: Setting dynamic payload format"); + static_cast<D*> (this)->setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) _audiocodec->getPayload(), _audiocodec->getClockRate())); + } else if (!_audiocodec->hasDynamicPayload() && _audiocodec->getPayload() != 9) { + _debug ("RTP: Setting static payload format"); + static_cast<D*> (this)->setPayloadFormat (ost::StaticPayloadFormat ( (ost::StaticPayloadType) _audiocodec->getPayload())); } - - template <typename D> - void AudioRtpSession<D>::setSessionMedia(AudioCodec* audiocodec) - { - _audiocodec = audiocodec; - - _debug ("RTP: Init codec payload %i", _audiocodec->getPayload()); - - _codecSampleRate = _audiocodec->getClockRate(); - _codecFrameSize = _audiocodec->getFrameSize(); - - // G722 requires timestamp to be incremented at 8 kHz - if (_audiocodec->getPayload() == 9) - _timestampIncrement = 160; - else - _timestampIncrement = _codecFrameSize; - - - _debug("RTP: Codec sampling rate: %d", _codecSampleRate); - _debug("RTP: Codec frame size: %d", _codecFrameSize); - _debug("RTP: RTP timestamp increment: %d", _timestampIncrement); - - // Even if specified as a 16 kHz codec, G722 requires rtp sending rate to be 8 kHz - if (_audiocodec->getPayload() == 9) { - _debug ("RTP: Setting G722 payload format"); - static_cast<D*>(this)->setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) _audiocodec->getPayload(), _audiocodec->getClockRate())); - } else if (_audiocodec->hasDynamicPayload()) { - _debug ("RTP: Setting dynamic payload format"); - static_cast<D*>(this)->setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) _audiocodec->getPayload(), _audiocodec->getClockRate())); - } else if (!_audiocodec->hasDynamicPayload() && _audiocodec->getPayload() != 9) { - _debug ("RTP: Setting static payload format"); - static_cast<D*>(this)->setPayloadFormat (ost::StaticPayloadFormat ( (ost::StaticPayloadType) _audiocodec->getPayload())); - } - if(_noiseState) { - speex_preprocess_state_destroy(_noiseState); - _noiseState = NULL; - } - - _noiseState = speex_preprocess_state_init(_codecSampleRate, _codecFrameSize); - int i=1; - speex_preprocess_ctl(_noiseState, SPEEX_PREPROCESS_SET_DENOISE, &i); - i=-20; - speex_preprocess_ctl(_noiseState, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &i); - i=0; - speex_preprocess_ctl(_noiseState, SPEEX_PREPROCESS_SET_AGC, &i); - i=8000; - speex_preprocess_ctl(_noiseState, SPEEX_PREPROCESS_SET_AGC_TARGET, &i); - i=16000; - speex_preprocess_ctl(_noiseState, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i); - i=0; - speex_preprocess_ctl(_noiseState, SPEEX_PREPROCESS_SET_DEREVERB, &i); - float f=0.0; - speex_preprocess_ctl(_noiseState, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f); - f=0.0; - speex_preprocess_ctl(_noiseState, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f); + if (_noiseState) { + speex_preprocess_state_destroy (_noiseState); + _noiseState = NULL; } - - template <typename D> - void AudioRtpSession<D>::setDestinationIpAddress(void) - { - if (_ca == NULL) { - _error ("RTP: Sipcall is gone."); - throw AudioRtpSessionException(); - } - - _info ("RTP: Setting IP address for the RTP session"); - // Store remote ip in case we would need to forget current destination - _remote_ip = ost::InetHostAddress(_ca->getLocalSDP()->get_remote_ip().c_str()); + _noiseState = speex_preprocess_state_init (_codecSampleRate, _codecFrameSize); + int i=1; + speex_preprocess_ctl (_noiseState, SPEEX_PREPROCESS_SET_DENOISE, &i); + i=-20; + speex_preprocess_ctl (_noiseState, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &i); + i=0; + speex_preprocess_ctl (_noiseState, SPEEX_PREPROCESS_SET_AGC, &i); + i=8000; + speex_preprocess_ctl (_noiseState, SPEEX_PREPROCESS_SET_AGC_TARGET, &i); + i=16000; + speex_preprocess_ctl (_noiseState, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i); + i=0; + speex_preprocess_ctl (_noiseState, SPEEX_PREPROCESS_SET_DEREVERB, &i); + float f=0.0; + speex_preprocess_ctl (_noiseState, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f); + f=0.0; + speex_preprocess_ctl (_noiseState, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f); +} - if (!_remote_ip) { - _warn("RTP: Target IP address (%s) is not correct!", - _ca->getLocalSDP()->get_remote_ip().data()); - return; - } +template <typename D> +void AudioRtpSession<D>::setDestinationIpAddress (void) +{ + if (_ca == NULL) { + _error ("RTP: Sipcall is gone."); + throw AudioRtpSessionException(); + } - // Store remote port in case we would need to forget current destination - _remote_port = (unsigned short) _ca->getLocalSDP()->get_remote_audio_port(); + _info ("RTP: Setting IP address for the RTP session"); - _info("RTP: New remote address for session: %s:%d", - _ca->getLocalSDP()->get_remote_ip().data(), _remote_port); + // Store remote ip in case we would need to forget current destination + _remote_ip = ost::InetHostAddress (_ca->getLocalSDP()->get_remote_ip().c_str()); - if (! static_cast<D*>(this)->addDestination (_remote_ip, _remote_port)) { - _warn("RTP: Can't add new destination to session!"); - return; - } + if (!_remote_ip) { + _warn ("RTP: Target IP address (%s) is not correct!", + _ca->getLocalSDP()->get_remote_ip().data()); + return; } - template <typename D> - void AudioRtpSession<D>::updateDestinationIpAddress(void) - { - // Destination address are stored in a list in ccrtp - // This method remove the current destination entry + // Store remote port in case we would need to forget current destination + _remote_port = (unsigned short) _ca->getLocalSDP()->get_remote_audio_port(); - if(!static_cast<D*>(this)->forgetDestination(_remote_ip, _remote_port, _remote_port+1)) - _warn("RTP: Could not remove previous destination"); + _info ("RTP: New remote address for session: %s:%d", + _ca->getLocalSDP()->get_remote_ip().data(), _remote_port); - // new destination is stored in call - // we just need to recall this method - setDestinationIpAddress(); + if (! static_cast<D*> (this)->addDestination (_remote_ip, _remote_port)) { + _warn ("RTP: Can't add new destination to session!"); + return; } - - template<typename D> - void AudioRtpSession<D>::putDtmfEvent(int digit) - { +} - sfl::DtmfEvent *dtmf = new sfl::DtmfEvent(); +template <typename D> +void AudioRtpSession<D>::updateDestinationIpAddress (void) +{ + // Destination address are stored in a list in ccrtp + // This method remove the current destination entry - dtmf->payload.event = digit; - dtmf->payload.ebit = false; // end of event bit - dtmf->payload.rbit = false; // reserved bit - dtmf->payload.duration = 1; // duration for this event - dtmf->newevent = true; - dtmf->length = 1000; + if (!static_cast<D*> (this)->forgetDestination (_remote_ip, _remote_port, _remote_port+1)) + _warn ("RTP: Could not remove previous destination"); - _eventQueue.push_back(dtmf); + // new destination is stored in call + // we just need to recall this method + setDestinationIpAddress(); +} - _debug("RTP: Put Dtmf Event %d", _eventQueue.size()); +template<typename D> +void AudioRtpSession<D>::putDtmfEvent (int digit) +{ - } + sfl::DtmfEvent *dtmf = new sfl::DtmfEvent(); + + dtmf->payload.event = digit; + dtmf->payload.ebit = false; // end of event bit + dtmf->payload.rbit = false; // reserved bit + dtmf->payload.duration = 1; // duration for this event + dtmf->newevent = true; + dtmf->length = 1000; + + _eventQueue.push_back (dtmf); - template<typename D> - void AudioRtpSession<D>::sendDtmfEvent(sfl::DtmfEvent *dtmf) - { - _debug("RTP: Send Dtmf %d", _eventQueue.size()); - - _timestamp += 160; - - // discard equivalent size of audio - processDataEncode(); - - // change Payload type for DTMF payload - static_cast<D*>(this)->setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) 101, 8000)); - - // Set marker in case this is a new Event - if(dtmf->newevent) - static_cast<D*>(this)->setMark (true); - - static_cast<D*>(this)->putData (_timestamp, (const unsigned char*)(&(dtmf->payload)), sizeof(ost::RTPPacket::RFC2833Payload)); - - // This is no more a new event - if(dtmf->newevent) { - dtmf->newevent = false; - static_cast<D*>(this)->setMark (false); - } - - // get back the payload to audio - static_cast<D*>(this)->setPayloadFormat (ost::StaticPayloadFormat ( (ost::StaticPayloadType) _audiocodec->getPayload())); - - // decrease length remaining to process for this event - dtmf->length -= 160; - - dtmf->payload.duration += 1; - - // next packet is going to be the last one - if((dtmf->length - 160) < 160) - dtmf->payload.ebit = true; - - if(dtmf->length < 160) { - delete dtmf; - _eventQueue.pop_front(); - } + _debug ("RTP: Put Dtmf Event %d", _eventQueue.size()); + +} + +template<typename D> +void AudioRtpSession<D>::sendDtmfEvent (sfl::DtmfEvent *dtmf) +{ + _debug ("RTP: Send Dtmf %d", _eventQueue.size()); + + _timestamp += 160; + + // discard equivalent size of audio + processDataEncode(); + + // change Payload type for DTMF payload + static_cast<D*> (this)->setPayloadFormat (ost::DynamicPayloadFormat ( (ost::PayloadType) 101, 8000)); + + // Set marker in case this is a new Event + if (dtmf->newevent) + static_cast<D*> (this)->setMark (true); + + static_cast<D*> (this)->putData (_timestamp, (const unsigned char*) (& (dtmf->payload)), sizeof (ost::RTPPacket::RFC2833Payload)); + + // This is no more a new event + if (dtmf->newevent) { + dtmf->newevent = false; + static_cast<D*> (this)->setMark (false); } - template <typename D> - bool onRTPPacketRecv(ost::IncomingRTPPkt&) - { - _debug("AudioRtpSession: onRTPPacketRecv"); + // get back the payload to audio + static_cast<D*> (this)->setPayloadFormat (ost::StaticPayloadFormat ( (ost::StaticPayloadType) _audiocodec->getPayload())); - return true; + // decrease length remaining to process for this event + dtmf->length -= 160; + + dtmf->payload.duration += 1; + + // next packet is going to be the last one + if ( (dtmf->length - 160) < 160) + dtmf->payload.ebit = true; + + if (dtmf->length < 160) { + delete dtmf; + _eventQueue.pop_front(); } +} +template <typename D> +bool onRTPPacketRecv (ost::IncomingRTPPkt&) +{ + _debug ("AudioRtpSession: onRTPPacketRecv"); - template <typename D> - int AudioRtpSession<D>::processDataEncode(void) - { - assert(_audiocodec); - assert(_audiolayer); + return true; +} - int _mainBufferSampleRate = _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate(); - // compute codec framesize in ms - float fixed_codec_framesize = computeCodecFrameSize (_audiocodec->getFrameSize(), _audiocodec->getClockRate()); +template <typename D> +int AudioRtpSession<D>::processDataEncode (void) +{ + assert (_audiocodec); + assert (_audiolayer); - // compute nb of byte to get coresponding to 20 ms at audio layer frame size (44.1 khz) - int maxBytesToGet = computeNbByteAudioLayer (fixed_codec_framesize); + int _mainBufferSampleRate = _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate(); - // available bytes inside ringbuffer - int availBytesFromMic = _manager->getAudioDriver()->getMainBuffer()->availForGet(_ca->getCallId()); + // compute codec framesize in ms + float fixed_codec_framesize = computeCodecFrameSize (_audiocodec->getFrameSize(), _audiocodec->getClockRate()); - // set available byte to maxByteToGet - int bytesAvail = (availBytesFromMic < maxBytesToGet) ? availBytesFromMic : maxBytesToGet; + // compute nb of byte to get coresponding to 20 ms at audio layer frame size (44.1 khz) + int maxBytesToGet = computeNbByteAudioLayer (fixed_codec_framesize); - if (bytesAvail == 0) - return 0; + // available bytes inside ringbuffer + int availBytesFromMic = _manager->getAudioDriver()->getMainBuffer()->availForGet (_ca->getCallId()); - // Get bytes from micRingBuffer to data_from_mic - int nbSample = _manager->getAudioDriver()->getMainBuffer()->getData(_micData , bytesAvail, 100, _ca->getCallId()) / sizeof (SFLDataFormat); + // set available byte to maxByteToGet + int bytesAvail = (availBytesFromMic < maxBytesToGet) ? availBytesFromMic : maxBytesToGet; - // nb bytes to be sent over RTP - int compSize = 0; + if (bytesAvail == 0) { + memset (_micDataEncoded, 0, sizeof (SFLDataFormat)); + return _audiocodec->getFrameSize(); + } - // test if resampling is required - if (_audiocodec->getClockRate() != _mainBufferSampleRate) { - int nb_sample_up = nbSample; + // Get bytes from micRingBuffer to data_from_mic + int nbSample = _manager->getAudioDriver()->getMainBuffer()->getData (_micData , bytesAvail, 100, _ca->getCallId()) / sizeof (SFLDataFormat); - _nSamplesMic = nbSample; + // nb bytes to be sent over RTP + int compSize = 0; - nbSample = _converter->downsampleData (_micData , _micDataConverted , _audiocodec->getClockRate(), _mainBufferSampleRate, nb_sample_up); + // test if resampling is required + if (_audiocodec->getClockRate() != _mainBufferSampleRate) { + int nb_sample_up = nbSample; - compSize = _audiocodec->codecEncode (_micDataEncoded, _micDataConverted, nbSample*sizeof (int16)); + _nSamplesMic = nbSample; - } else { + nbSample = _converter->downsampleData (_micData , _micDataConverted , _audiocodec->getClockRate(), _mainBufferSampleRate, nb_sample_up); - _nSamplesMic = nbSample; + compSize = _audiocodec->codecEncode (_micDataEncoded, _micDataConverted, nbSample*sizeof (int16)); - // no resampling required - compSize = _audiocodec->codecEncode (_micDataEncoded, _micData, nbSample*sizeof (int16)); - } + } else { + + _nSamplesMic = nbSample; - return compSize; + // no resampling required + compSize = _audiocodec->codecEncode (_micDataEncoded, _micData, nbSample*sizeof (int16)); } - - template <typename D> - void AudioRtpSession<D>::processDataDecode(unsigned char * spkrData, unsigned int size) { - if (_audiocodec != NULL) { + return compSize; +} +template <typename D> +void AudioRtpSession<D>::processDataDecode (unsigned char * spkrData, unsigned int size) +{ - int _mainBufferSampleRate = _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate(); + if (_audiocodec != NULL) { - // Return the size of data in bytes - int expandedSize = _audiocodec->codecDecode (_spkrDataDecoded , spkrData , size); - // buffer _receiveDataDecoded ----> short int or int16, coded on 2 bytes - int nbSample = expandedSize / sizeof (SFLDataFormat); + int _mainBufferSampleRate = _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate(); - // test if resampling is required - if (_audiocodec->getClockRate() != _mainBufferSampleRate) { + // Return the size of data in bytes + int expandedSize = _audiocodec->codecDecode (_spkrDataDecoded , spkrData , size); - // Do sample rate conversion - int nb_sample_down = nbSample; + // buffer _receiveDataDecoded ----> short int or int16, coded on 2 bytes + int nbSample = expandedSize / sizeof (SFLDataFormat); - nbSample = _converter->upsampleData (_spkrDataDecoded, _spkrDataConverted, _codecSampleRate, _mainBufferSampleRate, nb_sample_down); + // test if resampling is required + if (_audiocodec->getClockRate() != _mainBufferSampleRate) { - // Store the number of samples for recording - _nSamplesSpkr = nbSample; + // Do sample rate conversion + int nb_sample_down = nbSample; - speex_preprocess_run(_noiseState, _spkrDataConverted); + nbSample = _converter->upsampleData (_spkrDataDecoded, _spkrDataConverted, _codecSampleRate, _mainBufferSampleRate, nb_sample_down); - // put data in audio layer, size in byte - _manager->getAudioDriver()->getMainBuffer()->putData (_spkrDataConverted, nbSample * sizeof (SFLDataFormat), 100, _ca->getCallId()); + // Store the number of samples for recording + _nSamplesSpkr = nbSample; + speex_preprocess_run (_noiseState, _spkrDataConverted); - } else { - // Store the number of samples for recording - _nSamplesSpkr = nbSample; + // put data in audio layer, size in byte + _manager->getAudioDriver()->getMainBuffer()->putData (_spkrDataConverted, nbSample * sizeof (SFLDataFormat), 100, _ca->getCallId()); - // speex_preprocess_run(_noiseState, _spkrDataDecoded); - // put data in audio layer, size in byte - _manager->getAudioDriver()->getMainBuffer()->putData (_spkrDataDecoded, expandedSize, 100, _ca->getCallId()); - } + } else { + // Store the number of samples for recording + _nSamplesSpkr = nbSample; - // Notify (with a beep) an incoming call when there is already a call - if (_manager->incomingCallWaiting() > 0) { - _countNotificationTime += _time->getSecond(); - int countTimeModulo = _countNotificationTime % 5000; - // _debug("countNotificationTime: %d\n", countNotificationTime); - // _debug("countTimeModulo: %d\n", countTimeModulo); - if ((countTimeModulo - _countNotificationTime) < 0) { - _manager->notificationIncomingCall(); - } - - _countNotificationTime = countTimeModulo; - } + // speex_preprocess_run(_noiseState, _spkrDataDecoded); - } - } - - template <typename D> - void AudioRtpSession<D>::sendMicData() - { - // STEP: - // 1. get data from mic - // 2. convert it to int16 - good sample, good rate - // 3. encode it - // 4. send it - - // Increment timestamp for outgoing packet - _timestamp += _timestampIncrement; - - if (!_audiolayer) { - _debug ("No audiolayer available for MIC"); - return; + // put data in audio layer, size in byte + _manager->getAudioDriver()->getMainBuffer()->putData (_spkrDataDecoded, expandedSize, 100, _ca->getCallId()); } - if (!_audiocodec) { - _debug ("No audiocodec available for MIC"); - return; + // Notify (with a beep) an incoming call when there is already a call + if (_manager->incomingCallWaiting() > 0) { + _countNotificationTime += _time->getSecond(); + int countTimeModulo = _countNotificationTime % 5000; + + // _debug("countNotificationTime: %d\n", countNotificationTime); + // _debug("countTimeModulo: %d\n", countTimeModulo); + if ( (countTimeModulo - _countNotificationTime) < 0) { + _manager->notificationIncomingCall(); + } + + _countNotificationTime = countTimeModulo; } - int compSize = processDataEncode(); + } +} - // putData put the data on RTP queue, sendImmediate bypass this queue - static_cast<D*>(this)->putData (_timestamp, _micDataEncoded, compSize); +template <typename D> +void AudioRtpSession<D>::sendMicData() +{ + // STEP: + // 1. get data from mic + // 2. convert it to int16 - good sample, good rate + // 3. encode it + // 4. send it + + // Increment timestamp for outgoing packet + _timestamp += _timestampIncrement; + + if (!_audiolayer) { + _debug ("No audiolayer available for MIC"); + return; } - - - template <typename D> - void AudioRtpSession<D>::receiveSpeakerData () - { - if (!_audiolayer) { - _debug ("No audiolayer available for speaker"); - return; - } - if (!_audiocodec) { - _debug ("No audiocodec available for speaker"); - return; - } + if (!_audiocodec) { + _debug ("No audiocodec available for MIC"); + return; + } - const ost::AppDataUnit* adu = NULL; - int packetTimestamp = static_cast<D*>(this)->getFirstTimestamp(); - adu = static_cast<D*>(this)->getData(packetTimestamp); + int compSize = processDataEncode(); - if(!adu) - return; + // putData put the data on RTP queue, sendImmediate bypass this queue + static_cast<D*> (this)->putData (_timestamp, _micDataEncoded, compSize); +} - unsigned char* spkrDataIn = NULL; - unsigned int size = 0; - int result; - jb_frame frame; +template <typename D> +void AudioRtpSession<D>::receiveSpeakerData () +{ - _jbuffer->info.conf.resync_threshold = 0; + if (!_audiolayer) { + _debug ("No audiolayer available for speaker"); + return; + } - if (adu) { + if (!_audiocodec) { + _debug ("No audiocodec available for speaker"); + return; + } - spkrDataIn = (unsigned char*) adu->getData(); // data in char - size = adu->getSize(); // size in char + const ost::AppDataUnit* adu = NULL; - + int packetTimestamp = static_cast<D*> (this)->getFirstTimestamp(); - result = jb_put(_jbuffer, spkrDataIn, JB_TYPE_VOICE, _packetLength, _ts+=20, _currentTime); + adu = static_cast<D*> (this)->getData (packetTimestamp); - } - else { - _debug("No RTP packet available !!!!!!!!!!!!!!!!!!!!!!!\n"); - } + if (!adu) { + return; + } - result = jb_get(_jbuffer, &frame, _currentTime+=20, _packetLength); + unsigned char* spkrDataIn = NULL; + unsigned int size = 0; + int result; - // DTMF over RTP, size must be over 4 in order to process it as voice data - if(size > 4) { - processDataDecode(spkrDataIn, size); - //if(result == JB_OK) { - // processDataDecode((unsigned char *)(frame.data), 160); - //} - } + jb_frame frame; + + _jbuffer->info.conf.resync_threshold = 0; + + if (adu) { - delete adu; + spkrDataIn = (unsigned char*) adu->getData(); // data in char + size = adu->getSize(); // size in char + + result = jb_put (_jbuffer, spkrDataIn, JB_TYPE_VOICE, _packetLength, _ts+=20, _currentTime); + + } else { + _debug ("No RTP packet available !!!!!!!!!!!!!!!!!!!!!!!\n"); } - - template <typename D> - int AudioRtpSession<D>::startRtpThread (AudioCodec* audiocodec) - { - _debug("RTP: Starting main thread"); - setSessionTimeouts(); - setSessionMedia(audiocodec); - initBuffers(); - return start(_mainloopSemaphore); + + result = jb_get (_jbuffer, &frame, _currentTime+=20, _packetLength); + + // DTMF over RTP, size must be over 4 in order to process it as voice data + if (size > 4) { + processDataDecode (spkrDataIn, size); + //if(result == JB_OK) { + // processDataDecode((unsigned char *)(frame.data), 160); + //} } - - template <typename D> - void AudioRtpSession<D>::run () - { - // Timestamp must be initialized randomly - _timestamp = static_cast<D*>(this)->getCurrentTimestamp(); - - int sessionWaiting; - int threadSleep = 0; - - if (_codecSampleRate != 0){ - threadSleep = (_codecFrameSize * 1000) / _codecSampleRate; - } - else { - threadSleep = _layerFrameSize; - } - TimerPort::setTimer (threadSleep); - - if (_audiolayer == NULL) { - _error("RTP: Error: Audiolayer is null, cannot start the audio stream"); - throw AudioRtpSessionException(); - } + delete adu; +} + +template <typename D> +int AudioRtpSession<D>::startRtpThread (AudioCodec* audiocodec) +{ + _debug ("RTP: Starting main thread"); + setSessionTimeouts(); + setSessionMedia (audiocodec); + initBuffers(); + return start (_mainloopSemaphore); +} - _ca->setRecordingSmplRate(_audiocodec->getClockRate()); +template <typename D> +void AudioRtpSession<D>::run () +{ - // Start audio stream (if not started) AND flush all buffers (main and urgent) - _manager->getAudioDriver()->startStream(); - static_cast<D*>(this)->startRunning(); + // Timestamp must be initialized randomly + _timestamp = static_cast<D*> (this)->getCurrentTimestamp(); + int threadSleep = 0; - _debug ("RTP: Entering mainloop for call %s",_ca->getCallId().c_str()); + if (_codecSampleRate != 0) { + threadSleep = (_codecFrameSize * 1000) / _codecSampleRate; + } else { + threadSleep = _layerFrameSize; + } - while (!testCancel()) { + TimerPort::setTimer (threadSleep); - // Reset timestamp to make sure the timing information are up to date - if(_timestampCount > RTP_TIMESTAMP_RESET_FREQ) { - _timestamp = static_cast<D*>(this)->getCurrentTimestamp(); - _timestampCount = 0; - } - _timestampCount++; + if (_audiolayer == NULL) { + _error ("RTP: Error: Audiolayer is null, cannot start the audio stream"); + throw AudioRtpSessionException(); + } - - _manager->getAudioLayerMutex()->enter(); + _ca->setRecordingSmplRate (_audiocodec->getClockRate()); - // converterSamplingRate = _audiolayer->getMainBuffer()->getInternalSamplingRate(); - _converterSamplingRate = _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate(); + // Start audio stream (if not started) AND flush all buffers (main and urgent) + _manager->getAudioDriver()->startStream(); + static_cast<D*> (this)->startRunning(); - sessionWaiting = static_cast<D*>(this)->isWaiting(); - // Send session - if(_eventQueue.size() > 0) { - sendDtmfEvent(_eventQueue.front()); - } - else { - sendMicData (); - } + _debug ("RTP: Entering mainloop for call %s",_ca->getCallId().c_str()); - // Recv session - receiveSpeakerData (); + while (!testCancel()) { - /* + // Reset timestamp to make sure the timing information are up to date + if (_timestampCount > RTP_TIMESTAMP_RESET_FREQ) { + _timestamp = static_cast<D*> (this)->getCurrentTimestamp(); + _timestampCount = 0; + } - // Let's wait for the next transmit cycle - if (sessionWaiting == 1) { - // Record mic and speaker during conversation - _ca->recAudio.recData (_spkrDataDecoded, _micData, _nSamplesSpkr, _nSamplesMic); - } else { - // Record mic only while leaving a message - _ca->recAudio.recData (_micData,_nSamplesMic); - } - */ + _timestampCount++; - _manager->getAudioLayerMutex()->leave(); - // Let's wait for the next transmit cycle - Thread::sleep (TimerPort::getTimer()); - TimerPort::incTimer (threadSleep); + _manager->getAudioLayerMutex()->enter(); + + // converterSamplingRate = _audiolayer->getMainBuffer()->getInternalSamplingRate(); + _converterSamplingRate = _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate(); + + // Send session + if (_eventQueue.size() > 0) { + sendDtmfEvent (_eventQueue.front()); + } else { + sendMicData (); } - - _debug ("RTP: Left main loop for call%s", _ca->getCallId().c_str()); + + // Recv session + receiveSpeakerData (); + + _manager->getAudioLayerMutex()->leave(); + + // Let's wait for the next transmit cycle + Thread::sleep (TimerPort::getTimer()); + TimerPort::incTimer (threadSleep); } - + + _debug ("RTP: Left main loop for call%s", _ca->getCallId().c_str()); +} + } #endif // __AUDIO_RTP_SESSION_H__ diff --git a/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp b/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp index 097567f2dfeadb8915aa193be31faff2713b931a..1054624e58deb7395e275abb504ea15060efd31b 100644 --- a/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp +++ b/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp @@ -256,7 +256,7 @@ void AudioSrtpSession::initializeLocalCryptoContext (void) } - +#pragma GCC diagnostic ignored "-Wunused-value" char* AudioSrtpSession::encodeBase64 (unsigned char *input, int length) { BIO *b64, *bmem; @@ -288,6 +288,7 @@ char* AudioSrtpSession::encodeBase64 (unsigned char *input, int length) return buffer; } +#pragma GCC diagnostic warning "-Wunused-value" char* AudioSrtpSession::decodeBase64 (unsigned char *input, int length, int *length_out) { diff --git a/sflphone-common/src/audio/audiortp/AudioSrtpSession.h b/sflphone-common/src/audio/audiortp/AudioSrtpSession.h index 6b21cd329086c64ed6069dcaad53868d6668809c..48e6055df6a6c79caf36b456a8686d546552f6e0 100644 --- a/sflphone-common/src/audio/audiortp/AudioSrtpSession.h +++ b/sflphone-common/src/audio/audiortp/AudioSrtpSession.h @@ -11,7 +11,7 @@ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -40,8 +40,8 @@ class SdesNegotiator; class ManagerImpl; class SIPCall; -/* - Table from RFC 4568 6.2. Crypto-Suites, which define key parameters for supported +/* + Table from RFC 4568 6.2. Crypto-Suites, which define key parameters for supported cipher suite +---------------------+-------------+--------------+---------------+ @@ -64,75 +64,75 @@ class SIPCall; */ -namespace sfl { +namespace sfl +{ - class SrtpException: public std::exception - { - virtual const char* what() const throw() - { - return "ZRTP ZID initialization failed."; +class SrtpException: public std::exception +{ + virtual const char* what() const throw() { + return "ZRTP ZID initialization failed."; } - }; +}; + +class AudioSrtpSession : public ost::SymmetricRTPSession, public AudioRtpSession<AudioSrtpSession> +{ + public: - class AudioSrtpSession : public ost::SymmetricRTPSession, public AudioRtpSession<AudioSrtpSession> - { - public: + AudioSrtpSession (ManagerImpl * manager, SIPCall * sipcall); - AudioSrtpSession(ManagerImpl * manager, SIPCall * sipcall); + std::vector<std::string> getLocalCryptoInfo (void); - std::vector<std::string> getLocalCryptoInfo(void); + void setRemoteCryptoInfo (sfl::SdesNegotiator& nego); - void setRemoteCryptoInfo(sfl::SdesNegotiator& nego); + private: - private: + void initializeLocalMasterKey (void); - void initializeLocalMasterKey(void); + void initializeLocalMasterSalt (void); - void initializeLocalMasterSalt(void); + void initializeRemoteCryptoContext (void); - void initializeRemoteCryptoContext(void); + void initializeLocalCryptoContext (void); - void initializeLocalCryptoContext(void); + std::string getBase64ConcatenatedKeys(); - std::string getBase64ConcatenatedKeys(); + void unBase64ConcatenatedKeys (std::string base64keys); - void unBase64ConcatenatedKeys(std::string base64keys); + char* encodeBase64 (unsigned char *input, int length); - char* encodeBase64(unsigned char *input, int length); + char* decodeBase64 (unsigned char *input, int length, int *length_out); - char* decodeBase64(unsigned char *input, int length, int *length_out); + /** Default local crypto suite is AES_CM_128_HMAC_SHA1_80*/ + int _localCryptoSuite; - /** Default local crypto suite is AES_CM_128_HMAC_SHA1_80*/ - int _localCryptoSuite; + /** Remote crypto suite is initialized at AES_CM_128_HMAC_SHA1_80*/ + int _remoteCryptoSuite; - /** Remote crypto suite is initialized at AES_CM_128_HMAC_SHA1_80*/ - int _remoteCryptoSuite; + uint8 _localMasterKey[16]; - uint8 _localMasterKey[16]; + /** local master key length in byte */ + int _localMasterKeyLength; - /** local master key length in byte */ - int _localMasterKeyLength; + uint8 _localMasterSalt[14]; - uint8 _localMasterSalt[14]; + /** local master salt length in byte */ + int _localMasterSaltLength; - /** local master salt length in byte */ - int _localMasterSaltLength; + uint8 _remoteMasterKey[16]; - uint8 _remoteMasterKey[16]; + /** remote master key length in byte */ + int _remoteMasterKeyLength; - /** remote master key length in byte */ - int _remoteMasterKeyLength; + uint8 _remoteMasterSalt[14]; - uint8 _remoteMasterSalt[14]; + /** remote master salt length in byte */ + int _remoteMasterSaltLength; - /** remote master salt length in byte */ - int _remoteMasterSaltLength; + ost::CryptoContext* _remoteCryptoCtx; - ost::CryptoContext* _remoteCryptoCtx; + ost::CryptoContext* _localCryptoCtx; +}; - ost::CryptoContext* _localCryptoCtx; - }; - } #endif // __AUDIO_SRTP_SESSION_H__ diff --git a/sflphone-common/src/audio/audiortp/AudioSymmetricRtpSession.h b/sflphone-common/src/audio/audiortp/AudioSymmetricRtpSession.h index 0713f3db0c2cc82eb3d541a03f49d678f5d32776..a2275e3b508da1727d365fb03c2bfb10ff8bee80 100644 --- a/sflphone-common/src/audio/audiortp/AudioSymmetricRtpSession.h +++ b/sflphone-common/src/audio/audiortp/AudioSymmetricRtpSession.h @@ -10,7 +10,7 @@ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -35,17 +35,17 @@ class ManagerImpl; -namespace sfl { - class AudioSymmetricRtpSession : public ost::SymmetricRTPSession, public AudioRtpSession<AudioSymmetricRtpSession> - { - public: - AudioSymmetricRtpSession(ManagerImpl * manager, SIPCall * sipcall) : - ost::SymmetricRTPSession(ost::InetHostAddress(sipcall->getLocalIp().c_str()), sipcall->getLocalAudioPort()), - AudioRtpSession<AudioSymmetricRtpSession>(manager, sipcall) - { - _debug("AudioSymmetricRtpSession initialized\n"); - } - }; +namespace sfl +{ +class AudioSymmetricRtpSession : public ost::SymmetricRTPSession, public AudioRtpSession<AudioSymmetricRtpSession> +{ + public: + AudioSymmetricRtpSession (ManagerImpl * manager, SIPCall * sipcall) : + ost::SymmetricRTPSession (ost::InetHostAddress (sipcall->getLocalIp().c_str()), sipcall->getLocalAudioPort()), + AudioRtpSession<AudioSymmetricRtpSession> (manager, sipcall) { + _debug ("AudioSymmetricRtpSession initialized\n"); + } +}; } #endif // __AUDIO_SYMMETRIC_RTP_SESSION_H__ diff --git a/sflphone-common/src/audio/audiortp/AudioZrtpSession.h b/sflphone-common/src/audio/audiortp/AudioZrtpSession.h index f62515bcc9ad1712f59d49ecd6b91c9b5743bf1f..4eb68d364d8a6e057dc74de65bf2d13e9706dcc2 100644 --- a/sflphone-common/src/audio/audiortp/AudioZrtpSession.h +++ b/sflphone-common/src/audio/audiortp/AudioZrtpSession.h @@ -10,7 +10,7 @@ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -36,26 +36,26 @@ class ManagerImpl; class SIPCall; -namespace sfl { +namespace sfl +{ - class ZrtpZidException: public std::exception - { - virtual const char* what() const throw() - { - return "ZRTP ZID initialization failed."; +class ZrtpZidException: public std::exception +{ + virtual const char* what() const throw() { + return "ZRTP ZID initialization failed."; } - }; - - class AudioZrtpSession : public ost::SymmetricZRTPSession, public AudioRtpSession<AudioZrtpSession> - { - public: - AudioZrtpSession(ManagerImpl * manager, SIPCall * sipcall, const std::string& zidFilename); - - private: - void initializeZid(void); - std::string _zidFilename; - }; - +}; + +class AudioZrtpSession : public ost::SymmetricZRTPSession, public AudioRtpSession<AudioZrtpSession> +{ + public: + AudioZrtpSession (ManagerImpl * manager, SIPCall * sipcall, const std::string& zidFilename); + + private: + void initializeZid (void); + std::string _zidFilename; +}; + } #endif // __AUDIO_ZRTP_SESSION_H__ diff --git a/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.h b/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.h index 41e417e3f58aa0da0bca2f10e772bf08ee857145..f883e09dd8c5aec7de936995b3a4ad6aa972d087 100644 --- a/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.h +++ b/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.h @@ -27,7 +27,7 @@ * shall include the source code for the parts of OpenSSL used as well * as that of the covered work. */ - + #ifndef __SFL_ZRTP_CALLBACK_H__ #define __SFL_ZRTP_CALLBACK_H__ @@ -40,36 +40,37 @@ class SIPCall; class DBusManagerImpl; -namespace sfl { +namespace sfl +{ - class ZrtpSessionCallbackException: public std::exception - { - virtual const char* what() const throw() - { - return "An exception occured while being in a zrtp callback\n"; +class ZrtpSessionCallbackException: public std::exception +{ + virtual const char* what() const throw() { + return "An exception occured while being in a zrtp callback\n"; } - }; - - class ZrtpSessionCallback: public ZrtpUserCallback { +}; + +class ZrtpSessionCallback: public ZrtpUserCallback +{ public: - ZrtpSessionCallback(SIPCall *sipcall); + ZrtpSessionCallback (SIPCall *sipcall); - void secureOn(std::string cipher); - void secureOff(void); - void showSAS(std::string sas, bool verified); - void zrtpNotSuppOther(void); - void showMessage(GnuZrtpCodes::MessageSeverity sev, int32_t subCode); - void zrtpNegotiationFailed(GnuZrtpCodes::MessageSeverity severity, int subCode); + void secureOn (std::string cipher); + void secureOff (void); + void showSAS (std::string sas, bool verified); + void zrtpNotSuppOther (void); + void showMessage (GnuZrtpCodes::MessageSeverity sev, int32_t subCode); + void zrtpNegotiationFailed (GnuZrtpCodes::MessageSeverity severity, int subCode); void confirmGoClear(); - + private: SIPCall* _sipcall; - + static std::map<int32, std::string*> _infoMap; static std::map<int32, std::string*> _warningMap; static std::map<int32, std::string*> _severeMap; static std::map<int32, std::string*> _zrtpMap; static bool _mapInitialized; - }; +}; } #endif diff --git a/sflphone-common/src/audio/codecs/audiocodec.h b/sflphone-common/src/audio/codecs/audiocodec.h index d0d299ca8718fb0f153ec1318853c69c49a1f73d..485cf9d3042bceb0194514fbbbfc5e7b6d73dd87 100644 --- a/sflphone-common/src/audio/codecs/audiocodec.h +++ b/sflphone-common/src/audio/codecs/audiocodec.h @@ -8,12 +8,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -33,96 +33,115 @@ #ifndef _CODEC_AUDIO_H #define _CODEC_AUDIO_H -#include <string> +#include <string> #include <iostream> #include <dlfcn.h> -class AudioCodec { -protected: - /** Holds SDP-compliant codec name */ - std::string _codecName; // what we put inside sdp - - /** Clock rate or sample rate of the codec, in Hz */ - int _clockRate; - - /** Number of channel 1 = mono, 2 = stereo */ - int _channel; - - /** codec frame size in samples*/ - int _frameSize; - - /** Bitrate */ - double _bitrate; - /** Bandwidth */ - double _bandwidth; - -private: - int _payload; - bool _hasDynamicPayload; - bool _state; - -public: - AudioCodec(int payload, const std::string &codecName) - : _codecName(codecName), _clockRate(8000), _channel(1), _bitrate(0.0),_bandwidth(0),_payload(payload), _hasDynamicPayload(false),_state(true) { - - _hasDynamicPayload = (_payload >= 96 && _payload <= 127) ? true : false; - - // If g722 (payload 9), we need to init libccrtp symetric sessions with using - // dynamic payload format. This way we get control on rtp clockrate. - - if(_payload == 9) - { - _hasDynamicPayload = true; - } - -} - - AudioCodec( const AudioCodec& codec ) - : _codecName(codec._codecName), _clockRate(codec._clockRate), _channel(codec._channel), _bitrate(codec._bitrate),_bandwidth(codec._bandwidth),_payload(codec._payload), _hasDynamicPayload(false),_state(true) { - - _hasDynamicPayload = (_payload >= 96 && _payload <= 127) ? true : false; - - // If g722 (payload 9), we need to init libccrtp symetric sessions with using - // dynamic payload format. This way we get control on rtp clockrate. - - if(_payload == 9) - { - _hasDynamicPayload = true; - } - -} - - virtual ~AudioCodec() { - } - /** - * Decode an input buffer and fill the output buffer with the decoded data - * @return the number of bytes decoded - */ - virtual int codecDecode(short *, unsigned char *, unsigned int) = 0; - - /** - * Encode an input buffer and fill the output buffer with the encoded data - * @return the number of bytes encoded - */ - virtual int codecEncode(unsigned char *, short *, unsigned int) = 0; - - - /** Value used for SDP negotiation */ - std::string getCodecName( void ) { return _codecName; } - int getPayload( void ) { return _payload; } - bool hasDynamicPayload( void ) { return _hasDynamicPayload; } - int getClockRate( void ) { return _clockRate; } - int getFrameSize( void ) { return _frameSize; } - int getChannel( void ) { return _channel; } - bool getState( void ) { return _state; } - void setState(bool b) { _state = b; } - double getBitRate( void ) { return _bitrate; } - double getBandwidth( void ) { return _bandwidth; } +class AudioCodec +{ + protected: + /** Holds SDP-compliant codec name */ + std::string _codecName; // what we put inside sdp + + /** Clock rate or sample rate of the codec, in Hz */ + int _clockRate; + + /** Number of channel 1 = mono, 2 = stereo */ + int _channel; + + /** codec frame size in samples*/ + int _frameSize; + + /** Bitrate */ + double _bitrate; + /** Bandwidth */ + double _bandwidth; + + private: + int _payload; + bool _hasDynamicPayload; + bool _state; + + public: + AudioCodec (int payload, const std::string &codecName) + : _codecName (codecName), _clockRate (8000), _channel (1), _bitrate (0.0),_bandwidth (0),_payload (payload), _hasDynamicPayload (false),_state (true) { + + _hasDynamicPayload = (_payload >= 96 && _payload <= 127) ? true : false; + + // If g722 (payload 9), we need to init libccrtp symetric sessions with using + // dynamic payload format. This way we get control on rtp clockrate. + + if (_payload == 9) { + _hasDynamicPayload = true; + } + + } + + AudioCodec (const AudioCodec& codec) + : _codecName (codec._codecName), _clockRate (codec._clockRate), _channel (codec._channel), _bitrate (codec._bitrate),_bandwidth (codec._bandwidth),_payload (codec._payload), _hasDynamicPayload (false),_state (true) { + + _hasDynamicPayload = (_payload >= 96 && _payload <= 127) ? true : false; + + // If g722 (payload 9), we need to init libccrtp symetric sessions with using + // dynamic payload format. This way we get control on rtp clockrate. + + if (_payload == 9) { + _hasDynamicPayload = true; + } + + } + + virtual ~AudioCodec() { + } + /** + * Decode an input buffer and fill the output buffer with the decoded data + * @return the number of bytes decoded + */ + virtual int codecDecode (short *, unsigned char *, unsigned int) = 0; + + /** + * Encode an input buffer and fill the output buffer with the encoded data + * @return the number of bytes encoded + */ + virtual int codecEncode (unsigned char *, short *, unsigned int) = 0; + + + /** Value used for SDP negotiation */ + std::string getCodecName (void) { + return _codecName; + } + int getPayload (void) { + return _payload; + } + bool hasDynamicPayload (void) { + return _hasDynamicPayload; + } + int getClockRate (void) { + return _clockRate; + } + int getFrameSize (void) { + return _frameSize; + } + int getChannel (void) { + return _channel; + } + bool getState (void) { + return _state; + } + void setState (bool b) { + _state = b; + } + double getBitRate (void) { + return _bitrate; + } + double getBandwidth (void) { + return _bandwidth; + } }; // the types of the class factories typedef AudioCodec* create_t(); -typedef void destroy_t(AudioCodec*); +typedef void destroy_t (AudioCodec*); #endif diff --git a/sflphone-common/src/audio/codecs/codecDescriptor.h b/sflphone-common/src/audio/codecs/codecDescriptor.h index 9b5b1ea126f3e43b07a3679094d49b0a63af2d21..4393a0892afa37396eb11ce90cdef3d70ef6d00b 100644 --- a/sflphone-common/src/audio/codecs/codecDescriptor.h +++ b/sflphone-common/src/audio/codecs/codecDescriptor.h @@ -3,17 +3,17 @@ * Author: Yan Morin <yan.morin@savoirfairelinux.com> * Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com> * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * + * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -45,7 +45,7 @@ typedef std::pair<AudioCodec* , void*> CodecHandlePointer; /** Maps a pointer on an audiocodec object to a payload */ typedef std::map<AudioCodecType , AudioCodec*> CodecsMap; -/** A codec is identified by its payload. A payload is associated with a name. */ +/** A codec is identified by its payload. A payload is associated with a name. */ typedef std::map<AudioCodecType, std::string> CodecMap; /* @@ -53,189 +53,194 @@ typedef std::map<AudioCodecType, std::string> CodecMap; * @brief Handle audio codecs, load them in memory */ -class CodecDescriptor { - public: - /** - * Constructor - */ - CodecDescriptor(); - - /** - * Destructor - */ - ~CodecDescriptor(); - - /** - * Accessor to data structures - * @return CodecsMap& The available codec - */ - CodecsMap& getCodecsMap() { return _CodecsMap; } - - /** - * Accessor to data structures - * @return CodecOrder& The list that reflects the user's choice - */ - // CodecOrder& getActiveCodecs() { return _codecOrder; } - - /** - * Get codec name by its payload - * @param payload the payload looked for - * same as getPayload() - * @return std::string The name of the codec - */ - std::string getCodecName(AudioCodecType payload); - - /** - * Get the codec object associated with the payload - * @param payload The payload looked for - * @return AudioCodec* A pointer on a AudioCodec object - */ - AudioCodec* getCodec( AudioCodecType payload ); - - /** - * Initialiaze the map with all the supported codecs, even those inactive - */ - void init(); - - /** - * Set the default codecs order. - * This order will be apply to each account by default - */ - void setDefaultOrder(); - - /** - * Get the bit rate of the specified codec. - * @param payload The payload of the codec - * @return double The bit rate - */ - double getBitRate(AudioCodecType payload); - - /** - * Get the bandwidth for one call with the specified codec. - * The value has been calculated with the further information: - * RTp communication, SIP protocol (the value with IAX2 is very close), no RTCP, one simultaneous call, for one channel (the incoming one). - * @param payload The payload of the codec - * @return double The bandwidth - */ - double getBandwidthPerCall(AudioCodecType payload); - - /** - * Get the clock rate of the specified codec - * @param payload The payload of the codec - * @return int The clock rate of the specified codec - */ - int getSampleRate(AudioCodecType payload); - - /** - * Set the order of codecs by their payload - * @param list The ordered list sent by DBus - */ - void saveActiveCodecs(const std::vector<std::string>& list); - - /** - * Get the number of codecs loaded in dynamic memory - * @return int The number - */ - int getCodecsNumber( void ) { return _nbCodecs; } - - /** - * Unreferences the codecs loaded in memory - */ - void deleteHandlePointer( void ); - - /** - * Get the first element of the CodecsMap struct. - * i.e the one with the lowest payload - * @return AudioCodec The pointer on the codec object - */ - AudioCodec* getFirstCodecAvailable( void ); - - /** - * Instantiate a codec, used in AudioRTP to get an instance of Codec per call - * @param CodecHandlePointer The map containing the pointer on the object and the pointer on the handle function - */ - AudioCodec* instantiateCodec(AudioCodecType payload); - - /** - * For a given codec, return its specification - * - * @param payload The RTP payload of the codec - * @return std::vector <std::string> A vector containing codec's name, sample rate, bandwidth and bit rate - */ - std::vector <std::string> getCodecSpecifications (const int32_t& payload); - - /** - * Check if the audiocodec object has been successfully created - * @param payload The payload of the codec - * @return bool True if the audiocodec has been created - * false otherwise - */ - bool isCodecLoaded( int payload ); - - private: - - /** - * Scan the installation directory ( --prefix configure option ) - * And load the dynamic library - * @return std::vector<AudioCodec*> The list of the codec object successfully loaded in memory - */ - std::vector<AudioCodec *> scanCodecDirectory( void ); - - /** - * Load a codec - * @param std::string The path of the shared ( dynamic ) library. - * @return AudioCodec* the pointer of the object loaded. - */ - AudioCodec* loadCodec( std::string ); - - /** - * Unload a codec - * @param CodecHandlePointer The map containing the pointer on the object and the pointer on the handle function - */ - void unloadCodec( CodecHandlePointer ); - - /** - * Check if the files found in searched directories seems valid - * @param std::string The name of the file - * @return bool True if the file name begins with libcodec_ and ends with .so - * false otherwise - */ - bool seemsValid( std::string ); - - /** - * Check if the codecs shared library has already been scanned during the session - * Useful not to load twice the same codec saved in the different directory - * @param std::string The complete name of the shared directory ( without the path ) - * @return bool True if the codecs has been scanned - * false otherwise - */ - bool alreadyInCache( std::string ); - - /** - * Map the payload of a codec and the object associated ( AudioCodec * ) - */ - CodecsMap _CodecsMap; - - /** - * Vector containing a default order for the codecs - */ - CodecOrder _defaultCodecOrder; - - /** - * Vector containing the complete name of the codec shared library scanned - */ - std::vector<std::string> _Cache; - - /** - * Number of codecs loaded - */ - int _nbCodecs; - - /** - * Vector containing pairs - * Pair between pointer on function handle and pointer on audiocodec object - */ - std::vector< CodecHandlePointer > _CodecInMemory; +class CodecDescriptor +{ + public: + /** + * Constructor + */ + CodecDescriptor(); + + /** + * Destructor + */ + ~CodecDescriptor(); + + /** + * Accessor to data structures + * @return CodecsMap& The available codec + */ + CodecsMap& getCodecsMap() { + return _CodecsMap; + } + + /** + * Accessor to data structures + * @return CodecOrder& The list that reflects the user's choice + */ + // CodecOrder& getActiveCodecs() { return _codecOrder; } + + /** + * Get codec name by its payload + * @param payload the payload looked for + * same as getPayload() + * @return std::string The name of the codec + */ + std::string getCodecName (AudioCodecType payload); + + /** + * Get the codec object associated with the payload + * @param payload The payload looked for + * @return AudioCodec* A pointer on a AudioCodec object + */ + AudioCodec* getCodec (AudioCodecType payload); + + /** + * Initialiaze the map with all the supported codecs, even those inactive + */ + void init(); + + /** + * Set the default codecs order. + * This order will be apply to each account by default + */ + void setDefaultOrder(); + + /** + * Get the bit rate of the specified codec. + * @param payload The payload of the codec + * @return double The bit rate + */ + double getBitRate (AudioCodecType payload); + + /** + * Get the bandwidth for one call with the specified codec. + * The value has been calculated with the further information: + * RTp communication, SIP protocol (the value with IAX2 is very close), no RTCP, one simultaneous call, for one channel (the incoming one). + * @param payload The payload of the codec + * @return double The bandwidth + */ + double getBandwidthPerCall (AudioCodecType payload); + + /** + * Get the clock rate of the specified codec + * @param payload The payload of the codec + * @return int The clock rate of the specified codec + */ + int getSampleRate (AudioCodecType payload); + + /** + * Set the order of codecs by their payload + * @param list The ordered list sent by DBus + */ + void saveActiveCodecs (const std::vector<std::string>& list); + + /** + * Get the number of codecs loaded in dynamic memory + * @return int The number + */ + int getCodecsNumber (void) { + return _nbCodecs; + } + + /** + * Unreferences the codecs loaded in memory + */ + void deleteHandlePointer (void); + + /** + * Get the first element of the CodecsMap struct. + * i.e the one with the lowest payload + * @return AudioCodec The pointer on the codec object + */ + AudioCodec* getFirstCodecAvailable (void); + + /** + * Instantiate a codec, used in AudioRTP to get an instance of Codec per call + * @param CodecHandlePointer The map containing the pointer on the object and the pointer on the handle function + */ + AudioCodec* instantiateCodec (AudioCodecType payload); + + /** + * For a given codec, return its specification + * + * @param payload The RTP payload of the codec + * @return std::vector <std::string> A vector containing codec's name, sample rate, bandwidth and bit rate + */ + std::vector <std::string> getCodecSpecifications (const int32_t& payload); + + /** + * Check if the audiocodec object has been successfully created + * @param payload The payload of the codec + * @return bool True if the audiocodec has been created + * false otherwise + */ + bool isCodecLoaded (int payload); + + private: + + /** + * Scan the installation directory ( --prefix configure option ) + * And load the dynamic library + * @return std::vector<AudioCodec*> The list of the codec object successfully loaded in memory + */ + std::vector<AudioCodec *> scanCodecDirectory (void); + + /** + * Load a codec + * @param std::string The path of the shared ( dynamic ) library. + * @return AudioCodec* the pointer of the object loaded. + */ + AudioCodec* loadCodec (std::string); + + /** + * Unload a codec + * @param CodecHandlePointer The map containing the pointer on the object and the pointer on the handle function + */ + void unloadCodec (CodecHandlePointer); + + /** + * Check if the files found in searched directories seems valid + * @param std::string The name of the file + * @return bool True if the file name begins with libcodec_ and ends with .so + * false otherwise + */ + bool seemsValid (std::string); + + /** + * Check if the codecs shared library has already been scanned during the session + * Useful not to load twice the same codec saved in the different directory + * @param std::string The complete name of the shared directory ( without the path ) + * @return bool True if the codecs has been scanned + * false otherwise + */ + bool alreadyInCache (std::string); + + /** + * Map the payload of a codec and the object associated ( AudioCodec * ) + */ + CodecsMap _CodecsMap; + + /** + * Vector containing a default order for the codecs + */ + CodecOrder _defaultCodecOrder; + + /** + * Vector containing the complete name of the codec shared library scanned + */ + std::vector<std::string> _Cache; + + /** + * Number of codecs loaded + */ + int _nbCodecs; + + /** + * Vector containing pairs + * Pair between pointer on function handle and pointer on audiocodec object + */ + std::vector< CodecHandlePointer > _CodecInMemory; }; #endif // __CODEC_DESCRIPTOR_H__ diff --git a/sflphone-common/src/audio/codecs/g722.h b/sflphone-common/src/audio/codecs/g722.h index e4dcba29f55566103b7f4a3f8c3f3e23246bb594..e5061071500516c33b13c56d0786a77649bdb1ff 100644 --- a/sflphone-common/src/audio/codecs/g722.h +++ b/sflphone-common/src/audio/codecs/g722.h @@ -8,12 +8,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -48,8 +48,7 @@ codec is considerably faster, and still fully compatible with wideband terminals #include <stdint.h> -enum -{ +enum { G722_SAMPLE_RATE_8000 = 0x0001, G722_PACKED = 0x0002 }; @@ -61,8 +60,7 @@ enum #define INT16_MIN (-32768) #endif -typedef struct -{ +typedef struct { /*! TRUE if the operating in the special ITU test mode, with the band split filters disabled. */ int itu_test_mode; @@ -76,8 +74,7 @@ typedef struct /*! Signal history for the QMF */ int x[24]; - struct - { + struct { int s; int sp; int sz; @@ -99,8 +96,7 @@ typedef struct int out_bits; } g722_encode_state_t; -typedef struct -{ +typedef struct { /*! TRUE if the operating in the special ITU test mode, with the band split filters disabled. */ int itu_test_mode; @@ -114,8 +110,7 @@ typedef struct /*! Signal history for the QMF */ int x[24]; - struct - { + struct { int s; int sp; int sz; @@ -130,7 +125,7 @@ typedef struct int nb; int det; } band[2]; - + unsigned int in_buffer; int in_bits; unsigned int out_buffer; @@ -141,13 +136,13 @@ typedef struct extern "C" { #endif -void g722_encode_init (void); -int g722_encode_release(); -int g722_encode(uint8_t g722_data[], const int16_t amp[], int len); + void g722_encode_init (void); + int g722_encode_release(); + int g722_encode (uint8_t g722_data[], const int16_t amp[], int len); -void g722_decode_init (void); -int g722_decode_release(); -int g722_decode(int16_t amp[], const uint8_t g722_data[], int len); + void g722_decode_init (void); + int g722_decode_release(); + int g722_decode (int16_t amp[], const uint8_t g722_data[], int len); #ifdef __cplusplus } diff --git a/sflphone-common/src/audio/common.h b/sflphone-common/src/audio/common.h index 6f24a65bd53a50bbede077e18354d2ecbb548b88..058d611c3209a92560e0aaaaffa711936ebdc6af 100644 --- a/sflphone-common/src/audio/common.h +++ b/sflphone-common/src/audio/common.h @@ -1,17 +1,17 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. - * Author: + * Author: * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. diff --git a/sflphone-common/src/audio/dcblocker.cpp b/sflphone-common/src/audio/dcblocker.cpp index 7ff24a2678db35e68d243b22fa9100489f380f78..bb373f1b012d3c25fd6cc84c953b63e3d57f8739 100644 --- a/sflphone-common/src/audio/dcblocker.cpp +++ b/sflphone-common/src/audio/dcblocker.cpp @@ -42,9 +42,9 @@ void DcBlocker::reset() _ym1 = 0; } -void DcBlocker::putData (SFLDataFormat *inputData, int nbBytes) {} +void DcBlocker::putData (SFLDataFormat *inputData UNUSED, int nbBytes UNUSED) {} -int DcBlocker::getData (SFLDataFormat *outputData) +int DcBlocker::getData (SFLDataFormat *outputData UNUSED) { return 0; } @@ -87,4 +87,4 @@ int DcBlocker::process (SFLDataFormat *inputData, SFLDataFormat *outputData, int } -void DcBlocker::process (SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes) {} +void DcBlocker::process (SFLDataFormat *micData UNUSED, SFLDataFormat *spkrData UNUSED, SFLDataFormat *outputData UNUSED, int nbBytes UNUSED) {} diff --git a/sflphone-common/src/audio/dcblocker.h b/sflphone-common/src/audio/dcblocker.h index 8d53688c19ef15a03f49761ff3b3a315914f5bd3..021369139ac287551603ea133b981c9c31400a5a 100644 --- a/sflphone-common/src/audio/dcblocker.h +++ b/sflphone-common/src/audio/dcblocker.h @@ -36,49 +36,50 @@ #include <vector> -class DcBlocker : public Algorithm { +class DcBlocker : public Algorithm +{ -public: + public: - DcBlocker(); + DcBlocker(); - ~DcBlocker(); + ~DcBlocker(); - virtual void reset(void); + virtual void reset (void); - /** - * Unused - */ - virtual void putData(SFLDataFormat *inputData, int nbBytes); + /** + * Unused + */ + virtual void putData (SFLDataFormat *inputData, int nbBytes); - /** - * Unused - */ - virtual int getData(SFLDataFormat *outputData); + /** + * Unused + */ + virtual int getData (SFLDataFormat *outputData); - /** - * Perform dc blocking given the input data - */ - virtual void process(SFLDataFormat *data, int nbBytes); + /** + * Perform dc blocking given the input data + */ + virtual void process (SFLDataFormat *data, int nbBytes); - /** - * Perform echo cancellation using internal buffers - * \param inputData containing mixed echo and voice data - * \param outputData containing - */ - virtual int process(SFLDataFormat *inputData, SFLDataFormat *outputData, int nbBytes); + /** + * Perform echo cancellation using internal buffers + * \param inputData containing mixed echo and voice data + * \param outputData containing + */ + virtual int process (SFLDataFormat *inputData, SFLDataFormat *outputData, int nbBytes); - /** - * Perform echo cancellation, application must provide its own buffer - * \param micData containing mixed echo and voice data - * \param spkrData containing far-end voice data to be sent to speakers - * \param outputData containing the processed data - */ - virtual void process(SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes); + /** + * Perform echo cancellation, application must provide its own buffer + * \param micData containing mixed echo and voice data + * \param spkrData containing far-end voice data to be sent to speakers + * \param outputData containing the processed data + */ + virtual void process (SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes); -private: + private: - SFLDataFormat _y, _x, _xm1, _ym1; + SFLDataFormat _y, _x, _xm1, _ym1; }; #endif diff --git a/sflphone-common/src/audio/delaydetection.cpp b/sflphone-common/src/audio/delaydetection.cpp index 4d7e459c43ec259a231ab3c0867122224d210e59..e05739ce17cabde5500d464e826094d8f3115b77 100644 --- a/sflphone-common/src/audio/delaydetection.cpp +++ b/sflphone-common/src/audio/delaydetection.cpp @@ -32,7 +32,6 @@ #include "delaydetection.h" #include "math.h" -// #include <stdio.h> #include <string.h> #include <samplerate.h> @@ -169,7 +168,7 @@ void DelayDetection::putData (SFLDataFormat *inputData, int nbBytes) } -int DelayDetection::getData (SFLDataFormat *outputData) +int DelayDetection::getData (SFLDataFormat *outputData UNUSED) { return 0; } @@ -194,19 +193,6 @@ void DelayDetection::process (SFLDataFormat *inputData, int nbBytes) downsampleData (tmp, down, nbSamples, _downsamplingFactor); - /* - for(int i = 0; i < 10; i++) - _debug("up: %.10f", tmp[i]); - - for(int i = 0; i < 10; i++) - _debug("down: %.10f", down[i]); - - bandpassFilter(down, nbSamples/_downsamplingFactor); - - for(int i = 0; i < 10; i++) - _debug("band: %.10f", down[i]); - */ - memcpy (_captureDataDown+ (_nbMicSampleStored/_downsamplingFactor), down, (nbSamples/_downsamplingFactor) *sizeof (float)); _nbMicSampleStored += nbSamples; @@ -218,54 +204,33 @@ void DelayDetection::process (SFLDataFormat *inputData, int nbBytes) else return; - /* - for(int i = 0; i < 10; i++) - _debug("spkrRef: %.10f", _spkrReferenceDown[i]); - - for(int i = 0; i < 10; i++) - _debug("micSeg: %.10f", _captureDataDown[i]); - */ - _debug ("_spkrDownSize: %d, _micDownSize: %d", _spkrDownSize, _micDownSize); crossCorrelate (_spkrReferenceDown, _captureDataDown, _correlationResult, _micDownSize, _spkrDownSize); int maxIndex = getMaxIndex (_correlationResult, _spkrDownSize); _debug ("MaxIndex: %d", maxIndex); - - // reset(); } -int DelayDetection::process (SFLDataFormat *intputData, SFLDataFormat *outputData, int nbBytes) +int DelayDetection::process (SFLDataFormat *intputData UNUSED, SFLDataFormat *outputData UNUSED, int nbBytes UNUSED) { return 0; } -void DelayDetection::process (SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes) {} +void DelayDetection::process (SFLDataFormat *micData UNUSED, SFLDataFormat *spkrData UNUSED, SFLDataFormat *outputData UNUSED, int nbBytes UNUSED) {} void DelayDetection::crossCorrelate (float *ref, float *seg, float *res, int refSize, int segSize) { _debug ("CrossCorrelate"); - int counter = 0; - // Output has same size as the int rsize = refSize; int ssize = segSize; int tmpsize = segSize-refSize+1; - /* - for(int i = 0; i < 32; i++) - _debug("ref: %.10f", ref[i]); - - for(int i = 0; i < 150; i++) - _debug("seg: %.10f", seg[i]); - */ - // perform autocorrelation on reference signal float acref = correlate (ref, ref, rsize); - // _debug("acref: %f", acref); // perform crossrelation on signal float acseg = 0.0; @@ -274,7 +239,6 @@ void DelayDetection::crossCorrelate (float *ref, float *seg, float *res, int ref while (--tmpsize) { --ssize; acseg = correlate (seg+tmpsize, seg+tmpsize, rsize); - // _debug("acseg: %f", acseg); res[ssize] = correlate (ref, seg+tmpsize, rsize); r = sqrt (acref*acseg); @@ -289,7 +253,6 @@ void DelayDetection::crossCorrelate (float *ref, float *seg, float *res, int ref while (rsize) { acseg = correlate (seg, seg, rsize); - // _debug("acseg: %f", acseg); res[ssize-1] = correlate (ref+i, seg, rsize); r = sqrt (acref*acseg); @@ -321,8 +284,6 @@ double DelayDetection::correlate (float *sig1, float *sig2, short size) void DelayDetection::convertInt16ToFloat32 (SFLDataFormat *input, float *output, int nbSamples) { - // factor is 1/(2^15), used to rescale the short int range to the - // [-1.0 - 1.0] float range. #define S2F_FACTOR .000030517578125f; int len = nbSamples; @@ -336,26 +297,6 @@ void DelayDetection::convertInt16ToFloat32 (SFLDataFormat *input, float *output, void DelayDetection::downsampleData (float *input, float *output, int nbSamples, int factor) { - /* - float tmp[nbSamples]; - - for(int i = 0; i < nbSamples; i++) { - tmp[i] = _decimationFilter.getOutputSample(input[i]); - } - - int j; - for(j=_remainingIndex; j<nbSamples; j+=factor) { - output[j] = tmp[j]; - } - _remainingIndex = j - nbSamples; - */ - - /* - double downsampleFactor = (double) samplerate1 / samplerate2; - - int nbSamplesMax = (int) (samplerate1 * getFramesize() / 1000); - */ - int _src_err; SRC_STATE *_src_state = src_new (SRC_LINEAR, 1, &_src_err); @@ -371,13 +312,7 @@ void DelayDetection::downsampleData (float *input, float *output, int nbSamples, src_data.src_ratio = downfactor; src_data.end_of_input = 0; // More data will come - //src_short_to_float_array (dataIn, _floatBufferUpMic, nbSamples); - //_debug("downsample %d %f %d" , src_data.output_frames, src_data.src_ratio , nbSamples); src_process (_src_state, &src_data); - //_debug("downsample %d %f %d" , src_data.output_frames, src_data.src_ratio , nbSamples); - // nbSamples = (src_data.output_frames_gen > nbSamplesMax) ? nbSamplesMax : src_data.output_frames_gen; - //_debug("downsample %d %f %d" , src_data.output_frames, src_data.src_ratio , nbSamples); - // src_float_to_short_array (_floatBufferDownMic , dataOut , nbSamples); } } diff --git a/sflphone-common/src/audio/delaydetection.h b/sflphone-common/src/audio/delaydetection.h index a7567b6c2e8ccdfb82301724c5f151548517a8f2..4e0891084237386fb0cfb04e8de947dab0cd93b0 100644 --- a/sflphone-common/src/audio/delaydetection.h +++ b/sflphone-common/src/audio/delaydetection.h @@ -41,151 +41,153 @@ #define MAX_DELAY 150 // Size of internal buffers in samples -#define DELAY_BUFF_SIZE MAX_DELAY*8000/1000 +#define DELAY_BUFF_SIZE MAX_DELAY*8000/1000 #define MAXFILTERSIZE 100 -class FirFilter { +class FirFilter +{ - public: + public: - /** - * Constructor for this class - */ - FirFilter(std::vector<double> ir); + /** + * Constructor for this class + */ + FirFilter (std::vector<double> ir); - /** - * SDestructor for this class - */ - ~FirFilter(); - - /** - * Perform filtering on one sample - */ - float getOutputSample(float inputSample); + /** + * SDestructor for this class + */ + ~FirFilter(); - void reset(void); + /** + * Perform filtering on one sample + */ + float getOutputSample (float inputSample); + void reset (void); - private: - /** - * Length of the filter - */ - int _length; + private: - /** - * Coefficient of the filter - */ - std::vector<double> _impulseResponse; + /** + * Length of the filter + */ + int _length; - /** - * Circular buffer - */ - double _taps[MAXFILTERSIZE]; + /** + * Coefficient of the filter + */ + std::vector<double> _impulseResponse; + + /** + * Circular buffer + */ + double _taps[MAXFILTERSIZE]; + + /** + * Counter + */ + int _count; - /** - * Counter - */ - int _count; - }; -class DelayDetection : public Algorithm { +class DelayDetection : public Algorithm +{ - public: + public: - DelayDetection(); + DelayDetection(); - ~DelayDetection(); + ~DelayDetection(); - virtual void reset(void); + virtual void reset (void); - virtual void putData(SFLDataFormat *inputData, int nbBytes); + virtual void putData (SFLDataFormat *inputData, int nbBytes); - virtual int getData(SFLDataFormat *getData); + virtual int getData (SFLDataFormat *getData); - virtual void process(SFLDataFormat *inputData, int nbBytes); + virtual void process (SFLDataFormat *inputData, int nbBytes); - virtual int process(SFLDataFormat *inputData, SFLDataFormat *outputData, int nbBytes); + virtual int process (SFLDataFormat *inputData, SFLDataFormat *outputData, int nbBytes); - virtual void process(SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes); + virtual void process (SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes); - private: + private: - enum State { - WaitForSpeaker, - WaitForMic, - ComputeCorrelation - }; + enum State { + WaitForSpeaker, + WaitForMic, + ComputeCorrelation + }; - /** - * Perform a normalized crosscorrelation between template and segment - */ - void crossCorrelate(float *ref, float *seg, float *res, int refSize, int segSize); + /** + * Perform a normalized crosscorrelation between template and segment + */ + void crossCorrelate (float *ref, float *seg, float *res, int refSize, int segSize); - /** - * Perform a correlation on specified signals (mac) - */ - double correlate(float *sig1, float *sig2, short size); + /** + * Perform a correlation on specified signals (mac) + */ + double correlate (float *sig1, float *sig2, short size); - void convertInt16ToFloat32(SFLDataFormat *input, float *ouput, int nbSamples); + void convertInt16ToFloat32 (SFLDataFormat *input, float *ouput, int nbSamples); - void downsampleData(float *input, float *output, int nbSamples, int factor); + void downsampleData (float *input, float *output, int nbSamples, int factor); - void bandpassFilter(float *input, int nbSamples); + void bandpassFilter (float *input, int nbSamples); - int getMaxIndex(float *data, int size); + int getMaxIndex (float *data, int size); - State _internalState; + State _internalState; - FirFilter _decimationFilter; + FirFilter _decimationFilter; - FirFilter _bandpassFilter; + FirFilter _bandpassFilter; - /** - * Segment size in samples for correlation - */ - short _segmentSize; + /** + * Segment size in samples for correlation + */ + short _segmentSize; - int _downsamplingFactor; + int _downsamplingFactor; - /** - * Resulting correlation size (s + w -1) - */ - short _correlationSize; + /** + * Resulting correlation size (s + w -1) + */ + short _correlationSize; - float _spkrReference[WINDOW_SIZE*2]; + float _spkrReference[WINDOW_SIZE*2]; - float _capturedData[DELAY_BUFF_SIZE*2]; + float _capturedData[DELAY_BUFF_SIZE*2]; - float _spkrReferenceDown[WINDOW_SIZE*2]; + float _spkrReferenceDown[WINDOW_SIZE*2]; - float _captureDataDown[DELAY_BUFF_SIZE*2]; + float _captureDataDown[DELAY_BUFF_SIZE*2]; - float _spkrReferenceFilter[WINDOW_SIZE*2]; + float _spkrReferenceFilter[WINDOW_SIZE*2]; - float _captureDataFilter[DELAY_BUFF_SIZE*2]; + float _captureDataFilter[DELAY_BUFF_SIZE*2]; - float _correlationResult[DELAY_BUFF_SIZE*2]; + float _correlationResult[DELAY_BUFF_SIZE*2]; - int _remainingIndex; + int _remainingIndex; - int _spkrDownSize; + int _spkrDownSize; - int _micDownSize; + int _micDownSize; - int _nbMicSampleStored; + int _nbMicSampleStored; - int _nbSpkrSampleStored; + int _nbSpkrSampleStored; - public: + public: - friend class DelayDetectionTest; + friend class DelayDetectionTest; }; #endif diff --git a/sflphone-common/src/audio/echocancel.cpp b/sflphone-common/src/audio/echocancel.cpp index cc9df19de75181114956d41d9c0995b4e0a1804d..e6e2a3c92fbec4e3d7c6002da27466eaee400b3f 100644 --- a/sflphone-common/src/audio/echocancel.cpp +++ b/sflphone-common/src/audio/echocancel.cpp @@ -241,7 +241,7 @@ int EchoCancel::getData (SFLDataFormat *outputData) return copied; } -void EchoCancel::process (SFLDataFormat *data, int nbBytes) {} +void EchoCancel::process (SFLDataFormat *data UNUSED, int nbBytes UNUSED) {} int EchoCancel::process (SFLDataFormat *inputData, SFLDataFormat *outputData, int nbBytes) @@ -330,7 +330,7 @@ int EchoCancel::process (SFLDataFormat *inputData, SFLDataFormat *outputData, in return nbFrame * _smplPerFrame; } -void EchoCancel::process (SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes) +void EchoCancel::process (SFLDataFormat *micData UNUSED, SFLDataFormat *spkrData UNUSED, SFLDataFormat *outputData UNUSED, int nbBytes UNUSED) { } diff --git a/sflphone-common/src/audio/echocancel.h b/sflphone-common/src/audio/echocancel.h index e0ceda0445a67dc636a89df8874b21367b6a0c54..95cd987bac99250bf14347ab8608cddb71d06894 100644 --- a/sflphone-common/src/audio/echocancel.h +++ b/sflphone-common/src/audio/echocancel.h @@ -49,7 +49,7 @@ #define SPKR_LENGTH 80 #define MIC_LENGTH 80 -// Voice level threashold +// Voice level threashold #define MIN_SIG_LEVEL 250 // Delay between mic and speaker @@ -68,320 +68,329 @@ #define MIC_ADAPT_SIZE 100 // 1 sec #define SPKR_ADAPT_SIZE 20 // 200 ms -class EchoCancel : public Algorithm { - - public: - - EchoCancel(int smplRate = DEFAULT_SAMPLRATE, int frameLength = DEFAULT_FRAME_LENGTH); - - ~EchoCancel(); - - /** - * Reset echocanceller internal state at runtime. Usefull when making a new call - */ - virtual void reset(void); - - /** - * Add speaker data into internal buffer - * \param inputData containing far-end voice data to be sent to speakers - */ - virtual void putData(SFLDataFormat *inputData, int nbBytes); - - /** - * Get data ready to be played by speakers - */ - virtual int getData(SFLDataFormat *outputData); - - /** - * Unused - */ - virtual void process(SFLDataFormat *data, int nbBytes); - - /** - * Perform echo cancellation using internal buffers - * \param inputData containing mixed echo and voice data - * \param outputData containing - */ - virtual int process(SFLDataFormat *inputData, SFLDataFormat *outputData, int nbBytes); - - /** - * Perform echo cancellation, application must provide its own buffer - * \param micData containing mixed echo and voice data - * \param spkrData containing far-end voice data to be sent to speakers - * \param outputData containing the processed data - */ - virtual void process(SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes); - - /** - * Set echo canceller internal sampling rate, reset if sampling rate changed - */ - void setSamplingRate(int smplRate); - - /** - * Set echo canceller state to active/deactive - */ - void setEchoCancelState(bool state) { _echoActive = state; } - - /** - * Return the echo canceller state - */ - bool getEchoCancelState(void) { return _echoActive; } - - /** - * Set the noise suppression state to active/deactive - */ - void setNoiseSuppressState(bool state) { _noiseActive = state; } - - /** - * Return the noise suppression state - */ - bool getNoiseSuppressState(void) { return _noiseActive; } - - private: - - /** - * Actual method calld to supress echo from mic, micData and spkrData must be synchronized - */ - void performEchoCancel(SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData); - - /** - * This is the fall back method in case there is no spkr data available - */ - void performEchoCancelNoSpkr(SFLDataFormat *micData, SFLDataFormat *outputData); - - /** - * Compute current instantaneous microphone signal power and store it in internal array - */ - void updateMicLevel(SFLDataFormat *micData); - - /** - * Compute current instantaneous spkeaker signal power and store uit in internal array - */ - void updateSpkrLevel(SFLDataFormat *spkrData); - - /** - * Update speaker level array for both micData and spkrData - */ - void updateEchoCancel(SFLDataFormat *micData, SFLDataFormat *spkrData); - - /** - * Compute the average amplitude of the signal. - * \param data must be of SEGMENT_LENGTH long. - */ - int computeAmplitudeLevel(SFLDataFormat *data, int size); - - /** - * Compute amplitude signal - */ - SFLDataFormat estimatePower(SFLDataFormat *data, SFLDataFormat *ampl, int size, SFLDataFormat mem); - - /** - * Return the max amplitude provided any of _avgSpkrLevelHist or _avgMicLevelHist - */ - int getMaxAmplitude(int *data, int size); - - /** - * Apply gain factor on input buffer and copy result in output buffer. - * Buffers must be of SEGMENT_LENGTH long. - * \param input buffer - * \param output buffer - */ - void amplifySignal(SFLDataFormat *micData, SFLDataFormat *outputData, float amplify); - - /** - * Increase microphone gain by the provided factor. Sanity check are done internally. - */ - void increaseFactor(float factor); - - /** - * Decrease microphone gain. - */ - void decreaseFactor(); - - /** - * Perform simple correlation between data1 and data2 - */ - int performCorrelation(int *data1, int *data2, int size); - - /** - * Return maximum in data index - */ - int getMaximumIndex(int *data, int size); - - /** - * Internal buffer for mic data synchronization - */ - RingBuffer *_micData; - - /** - * Internal buffer for speaker data synchronization - */ - RingBuffer *_spkrData; - - RingBuffer *_spkrDataOut; - - /** - * Boolean value - */ - bool _spkrStoped; - - /** - * Internal buffer for audio processing - */ - SFLDataFormat _tmpSpkr[BUFF_SIZE]; - SFLDataFormat _tmpMic[BUFF_SIZE]; - SFLDataFormat _tmpOut[BUFF_SIZE]; - - /** - * Audio stream sampling rate - */ - int _samplingRate; - - /** - * Audio frame size in ms - */ - int _frameLength; - - /** - * Number of sample per frame - */ - int _smplPerFrame; - - /** - * Number of samples per segment - */ - int _smplPerSeg; - - /** - * Number of segment per frame - */ - int _nbSegmentPerFrame; - - /** - * Number of segment considered in history - * Mainly used to compute signal level - */ - int _micHistoryLength; - - int _spkrHistoryLength; - - /** - * Current playback level - */ - int _spkrLevel; - - /** - * Current capture level - */ - int _micLevel; - - /** - * Current index to store level in speaker history - */ - int _spkrHistCnt; - - /** - * Current index to store level in microphone history - */ - int _micHistCnt; - - /** - * Average speaker/microphone level history. Each value corespond to - * the averaged amplitude value over a segment (SEGMENT_LENGTH long) - */ - int _avgSpkrLevelHist[BUFF_SIZE]; - int _avgMicLevelHist[BUFF_SIZE]; - - /** - * Current linear gain factor to be applied on microphone - */ - float _amplFactor; - - /** - * Stored linea gain factor for lowpass filtering - */ - float _lastAmplFactor; - - /** - * Linear gain factor buffer to adjust to system's latency - */ - float _delayLineAmplify[MAX_DELAY_LINE_AMPL]; - - /** - * read/write for mic gain delay - */ - int _amplDelayIndexIn; - int _amplDelayIndexOut; - - /** - * State variable to determine if adaptation must be performed - */ - bool _adaptDone; - - /** - * State variable to specify if adaptation is started - */ - bool _adaptStarted; - - /** - * Adaptation index - */ - int _adaptCnt; - - /** - * Factor for power estimation - */ - float _alpha; - - /** - * Termporary spkr level memories - */ - SFLDataFormat _spkrLevelMem; - SFLDataFormat _micLevelMem; - - int _spkrAdaptCnt; - - int _micAdaptCnt; - - int _spkrAdaptSize; - - int _micAdaptSize; - - int _spkrAdaptArray[BUFF_SIZE]; - - int _micAdaptArray[BUFF_SIZE]; - - int _correlationSize; - - int _correlationArray[BUFF_SIZE]; - - int _processedByte; - - ofstream *micFile; - ofstream *spkrFile; - ofstream *echoFile; - - ofstream *micLevelData; - ofstream *spkrLevelData; - - // #ifdef HAVE_SPEEXDSP_LIB - /** - * Noise reduction processing state - */ - SpeexPreprocessState *_noiseState; - // #endif - - /** - * true if noise suppressor is active, false elsewhere - */ - bool _echoActive; - - /** - * true if noise suppressor is active, false elsewhere - */ - bool _noiseActive; - - DelayDetection _delayDetector; +class EchoCancel : public Algorithm +{ + + public: + + EchoCancel (int smplRate = DEFAULT_SAMPLRATE, int frameLength = DEFAULT_FRAME_LENGTH); + + ~EchoCancel(); + + /** + * Reset echocanceller internal state at runtime. Usefull when making a new call + */ + virtual void reset (void); + + /** + * Add speaker data into internal buffer + * \param inputData containing far-end voice data to be sent to speakers + */ + virtual void putData (SFLDataFormat *inputData, int nbBytes); + + /** + * Get data ready to be played by speakers + */ + virtual int getData (SFLDataFormat *outputData); + + /** + * Unused + */ + virtual void process (SFLDataFormat *data, int nbBytes); + + /** + * Perform echo cancellation using internal buffers + * \param inputData containing mixed echo and voice data + * \param outputData containing + */ + virtual int process (SFLDataFormat *inputData, SFLDataFormat *outputData, int nbBytes); + + /** + * Perform echo cancellation, application must provide its own buffer + * \param micData containing mixed echo and voice data + * \param spkrData containing far-end voice data to be sent to speakers + * \param outputData containing the processed data + */ + virtual void process (SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes); + + /** + * Set echo canceller internal sampling rate, reset if sampling rate changed + */ + void setSamplingRate (int smplRate); + + /** + * Set echo canceller state to active/deactive + */ + void setEchoCancelState (bool state) { + _echoActive = state; + } + + /** + * Return the echo canceller state + */ + bool getEchoCancelState (void) { + return _echoActive; + } + + /** + * Set the noise suppression state to active/deactive + */ + void setNoiseSuppressState (bool state) { + _noiseActive = state; + } + + /** + * Return the noise suppression state + */ + bool getNoiseSuppressState (void) { + return _noiseActive; + } + + private: + + /** + * Actual method calld to supress echo from mic, micData and spkrData must be synchronized + */ + void performEchoCancel (SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData); + + /** + * This is the fall back method in case there is no spkr data available + */ + void performEchoCancelNoSpkr (SFLDataFormat *micData, SFLDataFormat *outputData); + + /** + * Compute current instantaneous microphone signal power and store it in internal array + */ + void updateMicLevel (SFLDataFormat *micData); + + /** + * Compute current instantaneous spkeaker signal power and store uit in internal array + */ + void updateSpkrLevel (SFLDataFormat *spkrData); + + /** + * Update speaker level array for both micData and spkrData + */ + void updateEchoCancel (SFLDataFormat *micData, SFLDataFormat *spkrData); + + /** + * Compute the average amplitude of the signal. + * \param data must be of SEGMENT_LENGTH long. + */ + int computeAmplitudeLevel (SFLDataFormat *data, int size); + + /** + * Compute amplitude signal + */ + SFLDataFormat estimatePower (SFLDataFormat *data, SFLDataFormat *ampl, int size, SFLDataFormat mem); + + /** + * Return the max amplitude provided any of _avgSpkrLevelHist or _avgMicLevelHist + */ + int getMaxAmplitude (int *data, int size); + + /** + * Apply gain factor on input buffer and copy result in output buffer. + * Buffers must be of SEGMENT_LENGTH long. + * \param input buffer + * \param output buffer + */ + void amplifySignal (SFLDataFormat *micData, SFLDataFormat *outputData, float amplify); + + /** + * Increase microphone gain by the provided factor. Sanity check are done internally. + */ + void increaseFactor (float factor); + + /** + * Decrease microphone gain. + */ + void decreaseFactor(); + + /** + * Perform simple correlation between data1 and data2 + */ + int performCorrelation (int *data1, int *data2, int size); + + /** + * Return maximum in data index + */ + int getMaximumIndex (int *data, int size); + + /** + * Internal buffer for mic data synchronization + */ + RingBuffer *_micData; + + /** + * Internal buffer for speaker data synchronization + */ + RingBuffer *_spkrData; + + RingBuffer *_spkrDataOut; + + /** + * Boolean value + */ + bool _spkrStoped; + + /** + * Internal buffer for audio processing + */ + SFLDataFormat _tmpSpkr[BUFF_SIZE]; + SFLDataFormat _tmpMic[BUFF_SIZE]; + SFLDataFormat _tmpOut[BUFF_SIZE]; + + /** + * Audio stream sampling rate + */ + int _samplingRate; + + /** + * Audio frame size in ms + */ + int _frameLength; + + /** + * Number of sample per frame + */ + int _smplPerFrame; + + /** + * Number of samples per segment + */ + int _smplPerSeg; + + /** + * Number of segment per frame + */ + int _nbSegmentPerFrame; + + /** + * Number of segment considered in history + * Mainly used to compute signal level + */ + int _micHistoryLength; + + int _spkrHistoryLength; + + /** + * Factor for power estimation + */ + float _alpha; + + /** + * Termporary spkr level memories + */ + SFLDataFormat _spkrLevelMem; + SFLDataFormat _micLevelMem; + + /** + * Current playback level + */ + int _spkrLevel; + + /** + * Current capture level + */ + int _micLevel; + + /** + * Current index to store level in speaker history + */ + int _spkrHistCnt; + + /** + * Current index to store level in microphone history + */ + int _micHistCnt; + + /** + * Current linear gain factor to be applied on microphone + */ + float _amplFactor; + + /** + * Stored linea gain factor for lowpass filtering + */ + float _lastAmplFactor; + + /** + * read/write for mic gain delay + */ + int _amplDelayIndexIn; + int _amplDelayIndexOut; + + /** + * State variable to determine if adaptation must be performed + */ + bool _adaptDone; + + /** + * State variable to specify if adaptation is started + */ + bool _adaptStarted; + + /** + * Adaptation index + */ + int _adaptCnt; + + int _spkrAdaptCnt; + + int _micAdaptCnt; + + int _spkrAdaptSize; + + int _micAdaptSize; + + int _correlationSize; + + int _processedByte; + + /** + * true if noise suppressor is active, false elsewhere + */ + bool _echoActive; + + /** + * true if noise suppressor is active, false elsewhere + */ + bool _noiseActive; + + /** + * Average speaker/microphone level history. Each value corespond to + * the averaged amplitude value over a segment (SEGMENT_LENGTH long) + */ + int _avgSpkrLevelHist[BUFF_SIZE]; + int _avgMicLevelHist[BUFF_SIZE]; + + /** + * Linear gain factor buffer to adjust to system's latency + */ + float _delayLineAmplify[MAX_DELAY_LINE_AMPL]; + + int _spkrAdaptArray[BUFF_SIZE]; + + int _micAdaptArray[BUFF_SIZE]; + + int _correlationArray[BUFF_SIZE]; + + ofstream *micFile; + ofstream *spkrFile; + ofstream *echoFile; + + ofstream *micLevelData; + ofstream *spkrLevelData; + + // #ifdef HAVE_SPEEXDSP_LIB + /** + * Noise reduction processing state + */ + SpeexPreprocessState *_noiseState; + // #endif + + DelayDetection _delayDetector; }; diff --git a/sflphone-common/src/audio/jitterbuf.cpp b/sflphone-common/src/audio/jitterbuf.cpp index ac9335ee303748f4acd729f2900b270abd086792..4881498853e1ca7604e16d3bd6eee865b85d4dbc 100644 --- a/sflphone-common/src/audio/jitterbuf.cpp +++ b/sflphone-common/src/audio/jitterbuf.cpp @@ -124,7 +124,7 @@ static int longcmp (const void *a, const void *b) \note maybe later we can make the history buckets variable size, or something? */ /* drop parameter determines whether we will drop outliers to minimize * delay */ -static int history_put (jitterbuf *jb, long ts, long now, long ms) +static int history_put (jitterbuf *jb, long ts, long now) { long delay = now - (ts - jb->info.resync_offset); long threshold = 2 * jb->info.jitter + jb->info.conf.resync_threshold; @@ -539,7 +539,7 @@ jb_return_code jb_put (jitterbuf *jb, void *data, const enum jb_frame_type type, if (type == JB_TYPE_VOICE) { /* presently, I'm only adding VOICE frames to history and drift calculations; mostly because with the * IAX integrations, I'm sending retransmitted control frames with their awkward timestamps through */ - if (history_put (jb,ts,now,ms)) { + if (history_put (jb,ts,now)) { jb->info.frames_dropped++; return JB_DROP; } diff --git a/sflphone-common/src/audio/jitterbuf.h b/sflphone-common/src/audio/jitterbuf.h old mode 100755 new mode 100644 index 8de8bf0885d87f476550bc27c5201065d677b51d..2332968e5fe223567e032fea4c181e728c39f28c --- a/sflphone-common/src/audio/jitterbuf.h +++ b/sflphone-common/src/audio/jitterbuf.h @@ -14,7 +14,7 @@ */ /*! \file - * \brief + * \brief * jitterbuf: an application-independent jitterbuffer * \ref jitterbuf.c */ @@ -27,147 +27,147 @@ extern "C" { #endif -/*! \name configuration constants */ -/*@{ */ - /*! Number of historical timestamps to use in calculating jitter and drift */ -#define JB_HISTORY_SZ 500 - /*! what percentage of timestamps should we drop from the history when we examine it; - * this might eventually be something made configurable */ + /*! \name configuration constants */ + /*@{ */ + /*! Number of historical timestamps to use in calculating jitter and drift */ +#define JB_HISTORY_SZ 500 + /*! what percentage of timestamps should we drop from the history when we examine it; + * this might eventually be something made configurable */ #define JB_HISTORY_DROPPCT 3 - /*! the maximum droppct we can handle (say it was configurable). */ + /*! the maximum droppct we can handle (say it was configurable). */ #define JB_HISTORY_DROPPCT_MAX 4 - /*! the size of the buffer we use to keep the top and botton timestamps for dropping */ -#define JB_HISTORY_MAXBUF_SZ JB_HISTORY_SZ * JB_HISTORY_DROPPCT_MAX / 100 - /*! amount of additional jitterbuffer adjustment */ + /*! the size of the buffer we use to keep the top and botton timestamps for dropping */ +#define JB_HISTORY_MAXBUF_SZ JB_HISTORY_SZ * JB_HISTORY_DROPPCT_MAX / 100 + /*! amount of additional jitterbuffer adjustment */ #define JB_TARGET_EXTRA 40 - /*! ms between growing and shrinking; may not be honored if jitterbuffer runs out of space */ + /*! ms between growing and shrinking; may not be honored if jitterbuffer runs out of space */ #define JB_ADJUST_DELAY 40 -/*@} */ - -enum jb_return_code { - /* return codes */ - JB_OK, /* 0 */ - JB_EMPTY, /* 1 */ - JB_NOFRAME, /* 2 */ - JB_INTERP, /* 3 */ - JB_DROP, /* 4 */ - JB_SCHED /* 5 */ -}; - -enum jb_frame_type { - /* frame types */ - JB_TYPE_CONTROL, /*!< 0 */ - JB_TYPE_VOICE, /*!< 1 */ - JB_TYPE_VIDEO, /*!< 2 - reserved */ - JB_TYPE_SILENCE /*!< 3 */ -}; - -typedef struct jb_conf { - /* settings */ - long max_jitterbuf; /*!< defines a hard clamp to use in setting the jitter buffer delay */ - long resync_threshold; /*!< the jb will resync when delay increases to (2 * jitter) + this param */ - long max_contig_interp; /*!< the max interp frames to return in a row */ - long target_extra ; /*!< amount of additional jitterbuffer adjustment, overrides JB_TARGET_EXTRA */ -} jb_conf; - -typedef struct jb_info { - jb_conf conf; - - /* statistics */ - long frames_in; /*!< number of frames input to the jitterbuffer.*/ - long frames_out; /*!< number of frames output from the jitterbuffer.*/ - long frames_late; /*!< number of frames which were too late, and dropped.*/ - long frames_lost; /*!< number of missing frames.*/ - long frames_dropped; /*!< number of frames dropped (shrinkage) */ - long frames_ooo; /*!< number of frames received out-of-order */ - long frames_cur; /*!< number of frames presently in jb, awaiting delivery.*/ - long jitter; /*!< jitter measured within current history interval*/ - long min; /*!< minimum lateness within current history interval */ - long current; /*!< the present jitterbuffer adjustment */ - long target; /*!< the target jitterbuffer adjustment */ - long losspct; /*!< recent lost frame percentage (* 1000) */ - long next_voice_ts; /*!< the ts of the next frame to be read from the jb - in receiver's time */ - long last_voice_ms; /*!< the duration of the last voice frame */ - long silence_begin_ts; /*!< the time of the last CNG frame, when in silence */ - long last_adjustment; /*!< the time of the last adjustment */ - long last_delay; /*!< the last now added to history */ - long cnt_delay_discont; /*!< the count of discontinuous delays */ - long resync_offset; /*!< the amount to offset ts to support resyncs */ - long cnt_contig_interp; /*!< the number of contiguous interp frames returned */ -} jb_info; - -typedef struct jb_frame { - void *data; /* the frame data */ - long ts; /* the relative delivery time expected */ - long ms; /* the time covered by this frame, in sec/8000 */ - enum jb_frame_type type; /* the type of frame */ - struct jb_frame *next, *prev; -} jb_frame; - -typedef struct jitterbuf { - jb_info info; - - /* history */ - long history[JB_HISTORY_SZ]; /*!< history */ - int hist_ptr; /*!< points to index in history for next entry */ - long hist_maxbuf[JB_HISTORY_MAXBUF_SZ]; /*!< a sorted buffer of the max delays (highest first) */ - long hist_minbuf[JB_HISTORY_MAXBUF_SZ]; /*!< a sorted buffer of the min delays (lowest first) */ - int hist_maxbuf_valid; /*!< are the "maxbuf"/minbuf valid? */ - unsigned int dropem:1; /*!< flag to indicate dropping frames (overload) */ - - jb_frame *frames; /*!< queued frames */ - jb_frame *free; /*!< free frames (avoid malloc?) */ -} jitterbuf; - - -/*! \brief new jitterbuf */ -jitterbuf * jb_new(void); - -/*! \brief destroy jitterbuf */ -void jb_destroy(jitterbuf *jb); - -/*! \brief reset jitterbuf - * \note The jitterbuffer should be empty before you call this, otherwise - * you will leak queued frames, and some internal structures */ -void jb_reset(jitterbuf *jb); - -/*!\brief queue a frame - * - * data=frame data, timings (in ms): ms=length of frame (for voice), ts=ts (sender's time) - * now=now (in receiver's time) return value is one of - * JB_OK: Frame added. Last call to jb_next() still valid - * JB_DROP: Drop this frame immediately - * JB_SCHED: Frame added. Call jb_next() to get a new time for the next frame - */ -enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts, long now); - -/*! \brief get a frame for time now (receiver's time) return value is one of - * JB_OK: You've got frame! - * JB_DROP: Here's an audio frame you should just drop. Ask me again for this time.. - * JB_NOFRAME: There's no frame scheduled for this time. - * JB_INTERP: Please interpolate an interpl-length frame for this time (either we need to grow, or there was a lost frame) - * JB_EMPTY: The jb is empty. - */ -enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frame, long now, long interpl); - -/*! \brief unconditionally get frames from jitterbuf until empty */ -enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout); - -/*! \brief when is the next frame due out, in receiver's time (0=EMPTY) - * This value may change as frames are added (esp non-audio frames) */ -long jb_next(jitterbuf *jb); - -/*! \brief get jitterbuf info: only "statistics" may be valid */ -enum jb_return_code jb_getinfo(jitterbuf *jb, jb_info *stats); - -/* some diagnostics */ -void jb_dbginfo(jitterbuf *jb); - -/*! \brief set jitterbuf conf */ -enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf); - -typedef void __attribute__((format(printf, 1, 2))) (*jb_output_function_t)(const char *fmt, ...); -void jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg); + /*@} */ + + enum jb_return_code { + /* return codes */ + JB_OK, /* 0 */ + JB_EMPTY, /* 1 */ + JB_NOFRAME, /* 2 */ + JB_INTERP, /* 3 */ + JB_DROP, /* 4 */ + JB_SCHED /* 5 */ + }; + + enum jb_frame_type { + /* frame types */ + JB_TYPE_CONTROL, /*!< 0 */ + JB_TYPE_VOICE, /*!< 1 */ + JB_TYPE_VIDEO, /*!< 2 - reserved */ + JB_TYPE_SILENCE /*!< 3 */ + }; + + typedef struct jb_conf { + /* settings */ + long max_jitterbuf; /*!< defines a hard clamp to use in setting the jitter buffer delay */ + long resync_threshold; /*!< the jb will resync when delay increases to (2 * jitter) + this param */ + long max_contig_interp; /*!< the max interp frames to return in a row */ + long target_extra ; /*!< amount of additional jitterbuffer adjustment, overrides JB_TARGET_EXTRA */ + } jb_conf; + + typedef struct jb_info { + jb_conf conf; + + /* statistics */ + long frames_in; /*!< number of frames input to the jitterbuffer.*/ + long frames_out; /*!< number of frames output from the jitterbuffer.*/ + long frames_late; /*!< number of frames which were too late, and dropped.*/ + long frames_lost; /*!< number of missing frames.*/ + long frames_dropped; /*!< number of frames dropped (shrinkage) */ + long frames_ooo; /*!< number of frames received out-of-order */ + long frames_cur; /*!< number of frames presently in jb, awaiting delivery.*/ + long jitter; /*!< jitter measured within current history interval*/ + long min; /*!< minimum lateness within current history interval */ + long current; /*!< the present jitterbuffer adjustment */ + long target; /*!< the target jitterbuffer adjustment */ + long losspct; /*!< recent lost frame percentage (* 1000) */ + long next_voice_ts; /*!< the ts of the next frame to be read from the jb - in receiver's time */ + long last_voice_ms; /*!< the duration of the last voice frame */ + long silence_begin_ts; /*!< the time of the last CNG frame, when in silence */ + long last_adjustment; /*!< the time of the last adjustment */ + long last_delay; /*!< the last now added to history */ + long cnt_delay_discont; /*!< the count of discontinuous delays */ + long resync_offset; /*!< the amount to offset ts to support resyncs */ + long cnt_contig_interp; /*!< the number of contiguous interp frames returned */ + } jb_info; + + typedef struct jb_frame { + void *data; /* the frame data */ + long ts; /* the relative delivery time expected */ + long ms; /* the time covered by this frame, in sec/8000 */ + enum jb_frame_type type; /* the type of frame */ + struct jb_frame *next, *prev; + } jb_frame; + + typedef struct jitterbuf { + jb_info info; + + /* history */ + long history[JB_HISTORY_SZ]; /*!< history */ + int hist_ptr; /*!< points to index in history for next entry */ + long hist_maxbuf[JB_HISTORY_MAXBUF_SZ]; /*!< a sorted buffer of the max delays (highest first) */ + long hist_minbuf[JB_HISTORY_MAXBUF_SZ]; /*!< a sorted buffer of the min delays (lowest first) */ + int hist_maxbuf_valid; /*!< are the "maxbuf"/minbuf valid? */ + unsigned int dropem:1; /*!< flag to indicate dropping frames (overload) */ + + jb_frame *frames; /*!< queued frames */ + jb_frame *free; /*!< free frames (avoid malloc?) */ + } jitterbuf; + + + /*! \brief new jitterbuf */ + jitterbuf * jb_new (void); + + /*! \brief destroy jitterbuf */ + void jb_destroy (jitterbuf *jb); + + /*! \brief reset jitterbuf + * \note The jitterbuffer should be empty before you call this, otherwise + * you will leak queued frames, and some internal structures */ + void jb_reset (jitterbuf *jb); + + /*!\brief queue a frame + * + * data=frame data, timings (in ms): ms=length of frame (for voice), ts=ts (sender's time) + * now=now (in receiver's time) return value is one of + * JB_OK: Frame added. Last call to jb_next() still valid + * JB_DROP: Drop this frame immediately + * JB_SCHED: Frame added. Call jb_next() to get a new time for the next frame + */ + enum jb_return_code jb_put (jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts, long now); + + /*! \brief get a frame for time now (receiver's time) return value is one of + * JB_OK: You've got frame! + * JB_DROP: Here's an audio frame you should just drop. Ask me again for this time.. + * JB_NOFRAME: There's no frame scheduled for this time. + * JB_INTERP: Please interpolate an interpl-length frame for this time (either we need to grow, or there was a lost frame) + * JB_EMPTY: The jb is empty. + */ + enum jb_return_code jb_get (jitterbuf *jb, jb_frame *frame, long now, long interpl); + + /*! \brief unconditionally get frames from jitterbuf until empty */ + enum jb_return_code jb_getall (jitterbuf *jb, jb_frame *frameout); + + /*! \brief when is the next frame due out, in receiver's time (0=EMPTY) + * This value may change as frames are added (esp non-audio frames) */ + long jb_next (jitterbuf *jb); + + /*! \brief get jitterbuf info: only "statistics" may be valid */ + enum jb_return_code jb_getinfo (jitterbuf *jb, jb_info *stats); + + /* some diagnostics */ + void jb_dbginfo (jitterbuf *jb); + + /*! \brief set jitterbuf conf */ + enum jb_return_code jb_setconf (jitterbuf *jb, jb_conf *conf); + + typedef void __attribute__ ( (format (printf, 1, 2))) (*jb_output_function_t) (const char *fmt, ...); + void jb_setoutput (jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg); #ifdef __cplusplus } diff --git a/sflphone-common/src/audio/mainbuffer.cpp b/sflphone-common/src/audio/mainbuffer.cpp index 8dc6acbd4093037cda6b72878a4f29b0d32acd49..e30d810214e015a8615f15196370065c8bc49200 100644 --- a/sflphone-common/src/audio/mainbuffer.cpp +++ b/sflphone-common/src/audio/mainbuffer.cpp @@ -49,14 +49,16 @@ MainBuffer::~MainBuffer() void MainBuffer::setInternalSamplingRate (int sr) { - // ost::MutexLock guard (_mutex); if (sr != _internalSamplingRate) { - _internalSamplingRate = sr; - + // This call takes the mutex flushAllBuffers(); + ost::MutexLock guard (_mutex); + + _internalSamplingRate = sr; + Manager::instance().audioSamplingRateChanged(); } @@ -147,6 +149,8 @@ RingBuffer* MainBuffer::getRingBuffer (CallID call_id) RingBuffer* MainBuffer::createRingBuffer (CallID call_id) { + _debug ("BufferManager: Create ring buffer %s", call_id.c_str()); + RingBuffer* newRingBuffer = new RingBuffer (SIZEBUF, call_id); _ringBufferMap.insert (pair<CallID, RingBuffer*> (call_id, newRingBuffer)); @@ -158,6 +162,8 @@ RingBuffer* MainBuffer::createRingBuffer (CallID call_id) bool MainBuffer::removeRingBuffer (CallID call_id) { + _debug ("BufferManager: Remove Ringbuffer %s", call_id.c_str()); + RingBuffer* ring_buffer = getRingBuffer (call_id); if (ring_buffer != NULL) { @@ -178,7 +184,9 @@ bool MainBuffer::removeRingBuffer (CallID call_id) void MainBuffer::bindCallID (CallID call_id1, CallID call_id2) { - // ost::MutexLock guard (_mutex); + ost::MutexLock guard (_mutex); + + _debug ("BufferManager: Bind calls %s, %s", call_id1.c_str(), call_id2.c_str()); RingBuffer* ring_buffer; CallIDSet* callid_set; @@ -208,6 +216,8 @@ void MainBuffer::bindCallID (CallID call_id1, CallID call_id2) void MainBuffer::bindHalfDuplexOut (CallID process_id, CallID call_id) { + ost::MutexLock guard (_mutex); + // This method is used only for active calls, if this call does not exist, do nothing if (!getRingBuffer (call_id)) return; @@ -225,14 +235,14 @@ void MainBuffer::bindHalfDuplexOut (CallID process_id, CallID call_id) void MainBuffer::unBindCallID (CallID call_id1, CallID call_id2) { - // ost::MutexLock guard (_mutex); + ost::MutexLock guard (_mutex); + + _debug ("BufferManager: Unbind calls %s, %s", call_id1.c_str(), call_id2.c_str()); removeCallIDfromSet (call_id1, call_id2); removeCallIDfromSet (call_id2, call_id1); - RingBuffer* ringbuffer; - - ringbuffer = getRingBuffer (call_id2); + RingBuffer* ringbuffer = getRingBuffer (call_id2); if (ringbuffer) { @@ -248,6 +258,7 @@ void MainBuffer::unBindCallID (CallID call_id1, CallID call_id2) ringbuffer = getRingBuffer (call_id1); if (ringbuffer) { + ringbuffer->removeReadPointer (call_id2); if (ringbuffer->getNbReadPointer() == 0) { @@ -260,6 +271,8 @@ void MainBuffer::unBindCallID (CallID call_id1, CallID call_id2) void MainBuffer::unBindHalfDuplexOut (CallID process_id, CallID call_id) { + ost::MutexLock guard (_mutex); + removeCallIDfromSet (process_id, call_id); RingBuffer* ringbuffer = getRingBuffer (call_id); @@ -290,8 +303,6 @@ void MainBuffer::unBindHalfDuplexOut (CallID process_id, CallID call_id) void MainBuffer::unBindAll (CallID call_id) { - // ost::MutexLock guard (_mutex); - CallIDSet* callid_set = getCallIDSet (call_id); if (callid_set == NULL) @@ -340,6 +351,7 @@ void MainBuffer::unBindAllHalfDuplexOut (CallID process_id) int MainBuffer::putData (void *buffer, int toCopy, unsigned short volume, CallID call_id) { + ost::MutexLock guard (_mutex); RingBuffer* ring_buffer = getRingBuffer (call_id); @@ -365,6 +377,8 @@ int MainBuffer::putData (void *buffer, int toCopy, unsigned short volume, CallID int MainBuffer::availForPut (CallID call_id) { + ost::MutexLock guard (_mutex); + RingBuffer* ringbuffer = getRingBuffer (call_id); if (ringbuffer == NULL) @@ -377,6 +391,7 @@ int MainBuffer::availForPut (CallID call_id) int MainBuffer::getData (void *buffer, int toCopy, unsigned short volume, CallID call_id) { + ost::MutexLock guard (_mutex); CallIDSet* callid_set = getCallIDSet (call_id); @@ -399,7 +414,7 @@ int MainBuffer::getData (void *buffer, int toCopy, unsigned short volume, CallID return 0; } else { - memset (buffer, 0, nbSmplToCopy*sizeof (SFLDataFormat*)); + memset (buffer, 0, nbSmplToCopy*sizeof (SFLDataFormat)); int size = 0; @@ -407,6 +422,8 @@ int MainBuffer::getData (void *buffer, int toCopy, unsigned short volume, CallID while (iter_id != callid_set->end()) { + memset (mixBuffer, 0, toCopy); + size = getDataByID (mixBuffer, toCopy, volume, (CallID) (*iter_id), call_id); if (size > 0) { @@ -439,6 +456,8 @@ int MainBuffer::getDataByID (void *buffer, int toCopy, unsigned short volume, Ca int MainBuffer::availForGet (CallID call_id) { + ost::MutexLock guard (_mutex); + CallIDSet* callid_set = getCallIDSet (call_id); if (callid_set == NULL) @@ -464,6 +483,8 @@ int MainBuffer::availForGet (CallID call_id) int nb_bytes; CallIDSet::iterator iter_id = callid_set->begin(); + syncBuffers (call_id); + for (iter_id = callid_set->begin(); iter_id != callid_set->end(); iter_id++) { nb_bytes = availForGetByID (*iter_id, call_id); @@ -497,6 +518,7 @@ int MainBuffer::availForGetByID (CallID call_id, CallID reader_id) int MainBuffer::discard (int toDiscard, CallID call_id) { + ost::MutexLock guard (_mutex); CallIDSet* callid_set = getCallIDSet (call_id); @@ -524,7 +546,6 @@ int MainBuffer::discard (int toDiscard, CallID call_id) return toDiscard; } - } @@ -544,7 +565,7 @@ int MainBuffer::discardByID (int toDiscard, CallID call_id, CallID reader_id) void MainBuffer::flush (CallID call_id) { - // ost::MutexLock guard (_mutex); + ost::MutexLock guard (_mutex); CallIDSet* callid_set = getCallIDSet (call_id); @@ -571,7 +592,7 @@ void MainBuffer::flush (CallID call_id) void MainBuffer::flushDefault() { - // ost::MutexLock guard (_mutex); + ost::MutexLock guard (_mutex); flushByID (default_id, default_id); @@ -601,6 +622,46 @@ void MainBuffer::flushAllBuffers() } } +void MainBuffer:: syncBuffers (CallID call_id) +{ + + CallIDSet* callid_set = getCallIDSet (call_id); + + if (callid_set == NULL) + return; + + if (callid_set->empty()) { + _debug ("MainBuffer: CallIDSet with ID: \"%s\" is empty!", call_id.c_str()); + return; + } + + if (callid_set->size() == 1) { + // no need to resync, only one session + return; + } + + int nbBuffers = 0; + float mean_nbBytes = 0.0; + + CallIDSet::iterator iter_id = callid_set->begin(); + + + // compute mean nb byte in buffers + for (iter_id = callid_set->begin(); iter_id != callid_set->end(); iter_id++) { + nbBuffers++; + mean_nbBytes += availForGetByID (*iter_id, call_id); + } + + mean_nbBytes = mean_nbBytes / (float) nbBuffers; + + // resync buffers in this conference according to the computed mean + for (iter_id = callid_set->begin(); iter_id != callid_set->end(); iter_id++) { + + if (availForGetByID (*iter_id, call_id) > (mean_nbBytes + 640)) + discardByID (640, *iter_id, call_id); + } +} + void MainBuffer::stateInfo() { @@ -667,7 +728,4 @@ void MainBuffer::stateInfo() iter_buffer++; } - - - } diff --git a/sflphone-common/src/audio/mainbuffer.h b/sflphone-common/src/audio/mainbuffer.h index 95dd787ea4c8aab914fcdb0307afd4f7e2b89de4..31f8554496e5b57ccdbd1c200332bf1c5362bbd5 100644 --- a/sflphone-common/src/audio/mainbuffer.h +++ b/sflphone-common/src/audio/mainbuffer.h @@ -1,18 +1,18 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author : Alexandre Savard <alexandre.savard@savoirfairelinux.com> - * - * + * + * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -47,101 +47,113 @@ typedef std::set<CallID> CallIDSet; typedef std::map<CallID, CallIDSet*> CallIDMap; -class MainBuffer { +class MainBuffer +{ - public: + public: MainBuffer(); ~MainBuffer(); - void setInternalSamplingRate(int sr); + void setInternalSamplingRate (int sr); + + int getInternalSamplingRate() { + return _internalSamplingRate; + } - int getInternalSamplingRate() {return _internalSamplingRate;} + /** + * Bind together two audio streams so taht a client will be able + * to put and get data specifying its callid only. + */ + void bindCallID (CallID call_id1, CallID call_id2 = default_id); - CallIDSet* getCallIDSet(CallID call_id); + /** + * Add a new call_id to unidirectional outgoing stream + * \param call_id New call id to be added for this stream + * \param process_id Process that require this stream + */ + void bindHalfDuplexOut (CallID process_id, CallID call_id = default_id); - bool createCallIDSet(CallID set_id); + /** + * Unbind two calls + */ + void unBindCallID (CallID call_id1, CallID call_id2 = default_id); - bool removeCallIDSet(CallID set_id); + /** + * Unbind a unidirectional stream + */ + void unBindHalfDuplexOut (CallID process_id, CallID call_id = default_id); - /** - * Add a new call id to this set - */ - void addCallIDtoSet(CallID set_id, CallID call_id); + void unBindAll (CallID call_id); - void removeCallIDfromSet(CallID set_id, CallID call_id); + void unBindAllHalfDuplexOut (CallID process_id); - /** - * Create a new ringbuffer with default readpointer - */ - RingBuffer* createRingBuffer(CallID call_id); + int putData (void *buffer, int toCopy, unsigned short volume = 100, CallID call_id = default_id); - bool removeRingBuffer(CallID call_id); + int getData (void *buffer, int toCopy, unsigned short volume = 100, CallID call_id = default_id); - void bindCallID(CallID call_id1, CallID call_id2 = default_id); + int availForPut (CallID call_id = default_id); - /** - * Add a new call_id to unidirectional outgoing stream - * \param call_id New call id to be added for this stream - * \param process_id Process that require this stream - */ - void bindHalfDuplexOut(CallID process_id, CallID call_id = default_id); + int availForGet (CallID call_id = default_id); - /** - * Unbind two calls - */ - void unBindCallID(CallID call_id1, CallID call_id2 = default_id); + int discard (int toDiscard, CallID call_id = default_id); - void unBindHalfDuplexOut(CallID process_id, CallID call_id = default_id); + void flush (CallID call_id = default_id); - void unBindAll(CallID call_id); + void flushAllBuffers(); - void unBindAllHalfDuplexOut(CallID process_id); + void flushDefault(); - int putData(void *buffer, int toCopy, unsigned short volume = 100, CallID call_id = default_id); + void syncBuffers (CallID call_id); - int getData(void *buffer, int toCopy, unsigned short volume = 100, CallID call_id = default_id); + void stateInfo(); - int availForPut(CallID call_id = default_id); + private: - int availForGet(CallID call_id = default_id); + CallIDSet* getCallIDSet (CallID call_id); - int discard(int toDiscard, CallID call_id = default_id); + bool createCallIDSet (CallID set_id); - void flush(CallID call_id = default_id); + bool removeCallIDSet (CallID set_id); - void flushAllBuffers(); + /** + * Add a new call id to this set + */ + void addCallIDtoSet (CallID set_id, CallID call_id); - void flushDefault(); + void removeCallIDfromSet (CallID set_id, CallID call_id); - void stateInfo(); + /** + * Create a new ringbuffer with default readpointer + */ + RingBuffer* createRingBuffer (CallID call_id); - private: + bool removeRingBuffer (CallID call_id); - RingBuffer* getRingBuffer(CallID call_id); + RingBuffer* getRingBuffer (CallID call_id); - int getDataByID(void *buffer, int toCopy, unsigned short volume, CallID call_id, CallID reader_id); + int getDataByID (void *buffer, int toCopy, unsigned short volume, CallID call_id, CallID reader_id); - int availForGetByID(CallID call_id, CallID reader_id); + int availForGetByID (CallID call_id, CallID reader_id); - int discardByID(int toDiscard, CallID call_id, CallID reader_id); + int discardByID (int toDiscard, CallID call_id, CallID reader_id); - void flushByID(CallID call_id, CallID reader_id); + void flushByID (CallID call_id, CallID reader_id); - RingBufferMap _ringBufferMap; + RingBufferMap _ringBufferMap; - CallIDMap _callIDMap; + CallIDMap _callIDMap; - SFLDataFormat* mixBuffer; + SFLDataFormat* mixBuffer; - // ost::Mutex _mutex; + ost::Mutex _mutex; - int _internalSamplingRate; + int _internalSamplingRate; public: - friend class MainBufferTest; + friend class MainBufferTest; }; #endif diff --git a/sflphone-common/src/audio/pulseaudio/audiostream.cpp b/sflphone-common/src/audio/pulseaudio/audiostream.cpp index dd53993b772db89d459cc6ae779701cf9b78c185..5cffbbe4902326c36a19d70c819ee3d3793a8edd 100644 --- a/sflphone-common/src/audio/pulseaudio/audiostream.cpp +++ b/sflphone-common/src/audio/pulseaudio/audiostream.cpp @@ -68,7 +68,7 @@ AudioStream::connectStream (std::string* deviceName) return true; } -static void success_cb (pa_stream *s, int success, void *userdata) +static void success_cb (pa_stream *s, int success UNUSED, void *userdata) { assert (s); @@ -78,7 +78,6 @@ static void success_cb (pa_stream *s, int success, void *userdata) pa_threaded_mainloop_signal (mainloop, 0); } - bool AudioStream::drainStream (void) { @@ -213,10 +212,10 @@ AudioStream::createStream (pa_context* c, std::string *deviceName) if (_streamType == PLAYBACK_STREAM) { - attributes->maxlength = pa_usec_to_bytes (80 * PA_USEC_PER_MSEC, &_sample_spec); // -1; - attributes->tlength = pa_usec_to_bytes (40 * PA_USEC_PER_MSEC, &_sample_spec); + attributes->maxlength = pa_usec_to_bytes (160 * PA_USEC_PER_MSEC, &_sample_spec); // -1; + attributes->tlength = pa_usec_to_bytes (80 * PA_USEC_PER_MSEC, &_sample_spec); attributes->prebuf = 0; - attributes->fragsize = pa_usec_to_bytes (20 * PA_USEC_PER_MSEC, &_sample_spec); + attributes->fragsize = pa_usec_to_bytes (80 * PA_USEC_PER_MSEC, &_sample_spec); attributes->minreq = (uint32_t) -1; pa_threaded_mainloop_lock (_mainloop); @@ -231,10 +230,10 @@ AudioStream::createStream (pa_context* c, std::string *deviceName) } else if (_streamType == CAPTURE_STREAM) { - attributes->maxlength = pa_usec_to_bytes (80 * PA_USEC_PER_MSEC, &_sample_spec);// (uint32_t) -1; - attributes->tlength = pa_usec_to_bytes (40 * PA_USEC_PER_MSEC, &_sample_spec);// pa_usec_to_bytes (20 * PA_USEC_PER_MSEC, &_sample_spec); + attributes->maxlength = pa_usec_to_bytes (160 * PA_USEC_PER_MSEC, &_sample_spec);// (uint32_t) -1; + attributes->tlength = pa_usec_to_bytes (80 * PA_USEC_PER_MSEC, &_sample_spec);// pa_usec_to_bytes (20 * PA_USEC_PER_MSEC, &_sample_spec); attributes->prebuf = 0; - attributes->fragsize = pa_usec_to_bytes (20 * PA_USEC_PER_MSEC, &_sample_spec); // pa_usec_to_bytes (20 * PA_USEC_PER_MSEC, &_sample_spec); + attributes->fragsize = pa_usec_to_bytes (80 * PA_USEC_PER_MSEC, &_sample_spec); // pa_usec_to_bytes (20 * PA_USEC_PER_MSEC, &_sample_spec); attributes->minreq = (uint32_t) -1; pa_threaded_mainloop_lock (_mainloop); @@ -249,10 +248,10 @@ AudioStream::createStream (pa_context* c, std::string *deviceName) } else if (_streamType == RINGTONE_STREAM) { - attributes->maxlength = pa_usec_to_bytes (80 * PA_USEC_PER_MSEC, &_sample_spec);; - attributes->tlength = pa_usec_to_bytes (40 * PA_USEC_PER_MSEC, &_sample_spec); + attributes->maxlength = pa_usec_to_bytes (160 * PA_USEC_PER_MSEC, &_sample_spec);; + attributes->tlength = pa_usec_to_bytes (80 * PA_USEC_PER_MSEC, &_sample_spec); attributes->prebuf = 0; - attributes->fragsize = pa_usec_to_bytes (20 * PA_USEC_PER_MSEC, &_sample_spec); + attributes->fragsize = pa_usec_to_bytes (80 * PA_USEC_PER_MSEC, &_sample_spec); attributes->minreq = (uint32_t) -1; pa_threaded_mainloop_lock (_mainloop); diff --git a/sflphone-common/src/audio/pulseaudio/audiostream.h b/sflphone-common/src/audio/pulseaudio/audiostream.h index 20e199bf293134a18402189e22c9c1de013d4313..e4c48b94072d9e254f1705aa1ccf1e1265b62f77 100644 --- a/sflphone-common/src/audio/pulseaudio/audiostream.h +++ b/sflphone-common/src/audio/pulseaudio/audiostream.h @@ -6,12 +6,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -44,157 +44,168 @@ * This data structure contains the different king of audio streams available */ enum STREAM_TYPE { - PLAYBACK_STREAM, - CAPTURE_STREAM, - RINGTONE_STREAM, - UPLOAD_STREAM + PLAYBACK_STREAM, + CAPTURE_STREAM, + RINGTONE_STREAM, + UPLOAD_STREAM }; struct PulseLayerType { pa_context * context; pa_threaded_mainloop * mainloop; - + std::string description; - + int type; double volume; }; -class AudioStream { - public: - /** - * Constructor - * @param context The PulseLayerType structure containing various information. - */ - AudioStream(PulseLayerType * driver, int smplrate); - - /** - * Destructor - */ - ~AudioStream(); - - /** - * Write data to the main abstraction ring buffer. - * @param buffer The buffer containing the data to be played - * @param toCopy The number of samples, in bytes - * @return int The number of bytes played - */ - int putMain( void* buffer , int toCopy ); - - /** - * Write data to the urgent abstraction ring buffer. ( dtmf , double calls ) - * @param buffer The buffer containing the data to be played - * @param toCopy The number of samples, in bytes - * @return int The number of bytes played - */ - int putUrgent( void* buffer , int toCopy ); - - /** - * Connect the pulse audio stream - */ - bool connectStream(std::string* deviceName); - - /** - * Drain the given stream. - */ - bool drainStream(void); - - /** - * Disconnect the pulseaudio stream - */ - bool disconnectStream(); - - /** - * Accessor: Get the pulseaudio stream object - * @return pa_stream* The stream - */ - pa_stream* pulseStream(){ return _audiostream; } - - /** - * Accessor - * @return std::string The stream name - */ - std::string getStreamName( void ) { return _streamDescription; } - - /** - * Accessor - * @param name The stream name - */ - void setStreamName( std::string name ) { _streamDescription = name; } - - void setVolume( double pc ) { _volume.values[0] *= pc/100; } - pa_cvolume getVolume( void ) { return _volume; } - - /** - * Accessor - * @return stream state - */ - pa_stream_state_t getStreamState(void); - - - - private: - - // Copy Constructor - AudioStream(const AudioStream& rh); - - // Assignment Operator - AudioStream& operator=( const AudioStream& rh); - - /** - * Create the audio stream into the given context - * @param c The pulseaudio context - * @return pa_stream* The newly created audio stream - */ - pa_stream* createStream( pa_context* c, std::string* deviceName); - - /** - * Mandatory asynchronous callback on the audio stream state - */ - static void stream_state_callback( pa_stream* s, void* user_data ); - - /** - * Asynchronous callback on data processing ( write and read ) - */ - static void audioCallback ( pa_stream* s, size_t bytes, void* userdata ); - - /** - * Write data to the sound device - */ - void write( void ); - - /** - * The pulse audio object - */ - pa_stream* _audiostream; - - /** - * The pulse audio context - */ - pa_context* _context; - - /** - * The type of the stream - */ - int _streamType; - - /** - * The name of the stream - */ - std::string _streamDescription; - - /** - * Streams parameters - */ - pa_cvolume _volume; - pa_stream_flags_t _flag; - pa_sample_spec _sample_spec ; - - pa_threaded_mainloop * _mainloop; - - ost::Mutex _mutex; - - bool _stream_is_ready; +class AudioStream +{ + public: + /** + * Constructor + * @param context The PulseLayerType structure containing various information. + */ + AudioStream (PulseLayerType * driver, int smplrate); + + /** + * Destructor + */ + ~AudioStream(); + + /** + * Write data to the main abstraction ring buffer. + * @param buffer The buffer containing the data to be played + * @param toCopy The number of samples, in bytes + * @return int The number of bytes played + */ + int putMain (void* buffer , int toCopy); + + /** + * Write data to the urgent abstraction ring buffer. ( dtmf , double calls ) + * @param buffer The buffer containing the data to be played + * @param toCopy The number of samples, in bytes + * @return int The number of bytes played + */ + int putUrgent (void* buffer , int toCopy); + + /** + * Connect the pulse audio stream + */ + bool connectStream (std::string* deviceName); + + /** + * Drain the given stream. + */ + bool drainStream (void); + + /** + * Disconnect the pulseaudio stream + */ + bool disconnectStream(); + + /** + * Accessor: Get the pulseaudio stream object + * @return pa_stream* The stream + */ + pa_stream* pulseStream() { + return _audiostream; + } + + /** + * Accessor + * @return std::string The stream name + */ + std::string getStreamName (void) { + return _streamDescription; + } + + /** + * Accessor + * @param name The stream name + */ + void setStreamName (std::string name) { + _streamDescription = name; + } + + void setVolume (double pc) { + _volume.values[0] *= pc/100; + } + pa_cvolume getVolume (void) { + return _volume; + } + + /** + * Accessor + * @return stream state + */ + pa_stream_state_t getStreamState (void); + + + + private: + + // Copy Constructor + AudioStream (const AudioStream& rh); + + // Assignment Operator + AudioStream& operator= (const AudioStream& rh); + + /** + * Create the audio stream into the given context + * @param c The pulseaudio context + * @return pa_stream* The newly created audio stream + */ + pa_stream* createStream (pa_context* c, std::string* deviceName); + + /** + * Mandatory asynchronous callback on the audio stream state + */ + static void stream_state_callback (pa_stream* s, void* user_data); + + /** + * Asynchronous callback on data processing ( write and read ) + */ + static void audioCallback (pa_stream* s, size_t bytes, void* userdata); + + /** + * Write data to the sound device + */ + void write (void); + + /** + * The pulse audio object + */ + pa_stream* _audiostream; + + /** + * The pulse audio context + */ + pa_context* _context; + + /** + * The type of the stream + */ + int _streamType; + + /** + * The name of the stream + */ + std::string _streamDescription; + + /** + * Streams parameters + */ + pa_cvolume _volume; + pa_stream_flags_t _flag; + pa_sample_spec _sample_spec ; + + pa_threaded_mainloop * _mainloop; + + ost::Mutex _mutex; + + bool _stream_is_ready; }; diff --git a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp index 9bdf2ee0b760d8642817e2aac28e603a4787bf7f..84044628336dc56c68cddef637126790f6dd786a 100644 --- a/sflphone-common/src/audio/pulseaudio/pulselayer.cpp +++ b/sflphone-common/src/audio/pulseaudio/pulselayer.cpp @@ -63,40 +63,30 @@ static void ringtone_callback (pa_stream* s, size_t bytes, void* userdata) } - -static void stream_moved_callback (pa_stream *s, void *userdata) +static void stream_moved_callback (pa_stream *s, void *userdata UNUSED) { - int streamIndex = pa_stream_get_index (s); - int deviceIndex = pa_stream_get_device_index (s); - _debug ("stream_moved_callback: stream %d to %d", pa_stream_get_index (s), pa_stream_get_device_index (s)); - } -static void pa_success_callback (pa_context *c, int success, void *userdata) -{ - - _debug ("Audio: Success callback"); -} - -static void latency_update_callback (pa_stream *p, void *userdata) +static void latency_update_callback (pa_stream *p, void *userdata UNUSED) { pa_usec_t r_usec; pa_stream_get_latency (p, &r_usec, NULL); - // _debug ("Audio: Stream letency update %0.0f ms for device %s", (float) r_usec/1000, pa_stream_get_device_name (p)); - // _debug ("Audio: maxlength %u", pa_stream_get_buffer_attr (p)->maxlength); - // _debug ("Audio: tlength %u", pa_stream_get_buffer_attr (p)->tlength); - // _debug ("Audio: prebuf %u", pa_stream_get_buffer_attr (p)->prebuf); - // _debug ("Audio: minreq %u", pa_stream_get_buffer_attr (p)->minreq); - // _debug ("Audio: fragsize %u", pa_stream_get_buffer_attr (p)->fragsize); - + /* + _debug ("Audio: Stream letency update %0.0f ms for device %s", (float) r_usec/1000, pa_stream_get_device_name (p)); + _debug ("Audio: maxlength %u", pa_stream_get_buffer_attr (p)->maxlength); + _debug ("Audio: tlength %u", pa_stream_get_buffer_attr (p)->tlength); + _debug ("Audio: prebuf %u", pa_stream_get_buffer_attr (p)->prebuf); + _debug ("Audio: minreq %u", pa_stream_get_buffer_attr (p)->minreq); + _debug ("Audio: fragsize %u", pa_stream_get_buffer_attr (p)->fragsize); + */ } -static void sink_input_info_callback (pa_context *c, const pa_sink_info *i, int eol, void *userdata) +static void sink_input_info_callback (pa_context *c UNUSED, const pa_sink_info *i, int eol, void *userdata) { char s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX]; @@ -131,10 +121,9 @@ static void sink_input_info_callback (pa_context *c, const pa_sink_info *i, int ( (PulseLayer *) userdata)->getSinkList()->push_back (deviceName); } - } -static void source_input_info_callback (pa_context *c, const pa_source_info *i, int eol, void *userdata) +static void source_input_info_callback (pa_context *c UNUSED, const pa_source_info *i, int eol, void *userdata) { char s[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX]; @@ -228,28 +217,15 @@ static void context_changed_callback (pa_context* c, pa_subscription_event_type_ _debug ("Audio: Unknown event type"); } - -} - -/* -static void stream_suspended_callback (pa_stream *s UNUSED, void *userdata UNUSED) -{ - _debug("Audio: Stream Suspended"); } -*/ - -static void playback_underflow_callback (pa_stream* s, void* userdata UNUSED) +static void playback_underflow_callback (pa_stream* s UNUSED, void* userdata UNUSED) { - // _debug ("Audio: Buffer Underflow"); - // pa_stream_trigger (s, NULL, NULL); } static void playback_overflow_callback (pa_stream* s UNUSED, void* userdata UNUSED) { - // _debug ("Audio: Buffer OverFlow"); - } @@ -268,6 +244,8 @@ PulseLayer::PulseLayer (ManagerImpl* manager) AudioLayer::_echocancelstate = true; AudioLayer::_noisesuppressstate = true; + byteCounter = 0; + /* captureFile = new ofstream("captureFile", ofstream::binary); captureRsmplFile = new ofstream("captureRsmplFile", ofstream::binary); @@ -533,13 +511,13 @@ bool PulseLayer::createStreams (pa_context* c) // _debug("Device list size %d", getDevicelist()->size()); - std::string playbackDevice = _manager->getConfigString (AUDIO, PULSE_DEVICE_PLAYBACK); - std::string recordDevice = _manager->getConfigString (AUDIO, PULSE_DEVICE_PLAYBACK); - std::string ringtoneDevice = _manager->getConfigString (AUDIO, PULSE_DEVICE_PLAYBACK); + std::string playbackDevice = _manager->audioPreference.getDevicePlayback(); + std::string recordDevice = _manager->audioPreference.getDeviceRecord(); + std::string ringtoneDevice = _manager->audioPreference.getDeviceRingtone(); _debug ("Audio: Device stored in config for playback: %s", playbackDevice.c_str()); - _debug ("Audio: Device stored in config for ringtone: %s", recordDevice.c_str()); - _debug ("Audio: Device stored in config for record: %s", ringtoneDevice.c_str()); + _debug ("Audio: Device stored in config for record: %s", recordDevice.c_str()); + _debug ("Audio: Device stored in config for ringtone: %s", ringtoneDevice.c_str()); PulseLayerType * playbackParam = new PulseLayerType(); playbackParam->context = c; @@ -632,8 +610,8 @@ void PulseLayer::closeCaptureStream (void) if (record) { std::string deviceName (pa_stream_get_device_name (record->pulseStream())); - _debug ("record device to be stored in config: %s", deviceName.c_str()); - _manager->setConfig (AUDIO, PULSE_DEVICE_RECORD, deviceName); + _debug ("Audio: record device to be stored in config: %s", deviceName.c_str()); + _manager->audioPreference.setDeviceRecord (deviceName); delete record; record=NULL; } @@ -644,16 +622,16 @@ void PulseLayer::closePlaybackStream (void) { if (playback) { std::string deviceName (pa_stream_get_device_name (playback->pulseStream())); - _debug ("playback device to be stored in config: %s", deviceName.c_str()); - _manager->setConfig (AUDIO, PULSE_DEVICE_PLAYBACK, deviceName); + _debug ("Audio: playback device to be stored in config: %s", deviceName.c_str()); + _manager->audioPreference.setDevicePlayback (deviceName); delete playback; playback=NULL; } if (ringtone) { std::string deviceName (pa_stream_get_device_name (ringtone->pulseStream())); - _debug ("ringtone device to be stored in config: %s", deviceName.c_str()); - _manager->setConfig (AUDIO, PULSE_DEVICE_RINGTONE, deviceName); + _debug ("Audio: ringtone device to be stored in config: %s", deviceName.c_str()); + _manager->audioPreference.setDeviceRingtone (deviceName); delete ringtone; ringtone = NULL; } @@ -669,15 +647,6 @@ int PulseLayer::canGetMic() } -int PulseLayer::getMic (void *buffer, int toCopy) -{ - if (record) { - return 0; - } else - return 0; -} - - void PulseLayer::startStream (void) { if (_audiofilter) @@ -813,7 +782,6 @@ void PulseLayer::writeToSpeaker (void) SFLDataFormat* out;// = (SFLDataFormat*)pa_xmalloc(framesPerBuffer); urgentAvailBytes = _urgentRingBuffer.AvailForGet(); - // available bytes to be written in pulseaudio internal buffer int writeableSize = pa_stream_writable_size (playback->pulseStream()); @@ -836,12 +804,16 @@ void PulseLayer::writeToSpeaker (void) } else { + // Get ringtone AudioLoop* tone = _manager->getTelephoneTone(); + // We must test if data have been received from network in case of early media + normalAvailBytes = getMainBuffer()->availForGet(); + // flush remaining samples in _urgentRingBuffer flushUrgent(); - if (tone != 0) { + if ( (tone != 0) && (normalAvailBytes <= 0)) { if (playback->getStreamState() == PA_STREAM_READY) { @@ -860,9 +832,7 @@ void PulseLayer::writeToSpeaker (void) int maxNbBytesToGet = 0; - // test if audio resampling is needed - if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) { // upsamplefactor is used to compute the number of bytes to get in the ring buffer @@ -877,8 +847,6 @@ void PulseLayer::writeToSpeaker (void) } - normalAvailBytes = getMainBuffer()->availForGet(); - byteToGet = (normalAvailBytes < (int) (maxNbBytesToGet)) ? normalAvailBytes : maxNbBytesToGet; if (byteToGet) { @@ -919,8 +887,9 @@ void PulseLayer::writeToSpeaker (void) } + // Copy far-end signal in echo canceller to adapt filter coefficient - AudioLayer::_echoCanceller->putData (out, byteToGet); + // AudioLayer::_echoCanceller->putData(out, byteToGet); pa_xfree (out); @@ -988,11 +957,12 @@ void PulseLayer::readFromMic (void) // captureFilterFile->write ((const char *)rsmpl_out, nbSample*sizeof(SFLDataFormat)); // echo cancellation processing - int sampleready = _echoCanceller->processAudio (rsmpl_out, echoCancelledMic, nbSample*sizeof (SFLDataFormat)); + // int sampleready = _echoCanceller->processAudio(rsmpl_out, echoCancelledMic, nbSample*sizeof(SFLDataFormat)); // getMainBuffer()->putData ( (void*) rsmpl_out, nbSample*sizeof (SFLDataFormat), 100); - if (sampleready) - getMainBuffer()->putData (echoCancelledMic, sampleready*sizeof (SFLDataFormat), 100); + // if(sampleready) + // getMainBuffer()->putData ( echoCancelledMic, sampleready*sizeof (SFLDataFormat), 100); + getMainBuffer()->putData (rsmpl_out, nbSample*sizeof (SFLDataFormat), 100); pa_xfree (rsmpl_out); @@ -1004,10 +974,11 @@ void PulseLayer::readFromMic (void) _audiofilter->processAudio ( (SFLDataFormat *) data, filter_out, r); // echo cancellation processing - int sampleready = _echoCanceller->processAudio ( (SFLDataFormat *) filter_out, echoCancelledMic, r); + // int sampleready = _echoCanceller->processAudio((SFLDataFormat *)filter_out, echoCancelledMic, r); // no resampling required - getMainBuffer()->putData (echoCancelledMic, sampleready*sizeof (SFLDataFormat), 100); + // getMainBuffer()->putData (echoCancelledMic, sampleready*sizeof (SFLDataFormat), 100); + getMainBuffer()->putData (filter_out, r, 100); pa_xfree (filter_out); } @@ -1025,8 +996,6 @@ void PulseLayer::readFromMic (void) void PulseLayer::ringtoneToSpeaker (void) { - int availBytes; - AudioLoop* file_tone = _manager->getTelephoneFile(); SFLDataFormat* out; diff --git a/sflphone-common/src/audio/pulseaudio/pulselayer.h b/sflphone-common/src/audio/pulseaudio/pulselayer.h index d13c1e69385a45e1f5c31afabfcd8e2b1a7d2e1b..2cfb2595d17e473c2b4fa9b8e9aafd166c94e061 100644 --- a/sflphone-common/src/audio/pulseaudio/pulselayer.h +++ b/sflphone-common/src/audio/pulseaudio/pulselayer.h @@ -7,12 +7,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -54,242 +54,261 @@ class ManagerImpl; typedef std::list<std::string> DeviceList; -class PulseLayer : public AudioLayer { - public: - PulseLayer(ManagerImpl* manager); - ~PulseLayer(void); - - void openLayer( void ); - - bool closeLayer( void ); - - /** - * Check if no devices are opened, otherwise close them. - * Then open the specified devices by calling the private functions open_device - * @param indexIn The number of the card chosen for capture - * @param indexOut The number of the card chosen for playback - * @param sampleRate The sample rate - * @param frameSize The frame size - * @param stream To indicate which kind of stream you want to open - * SFL_PCM_CAPTURE - * SFL_PCM_PLAYBACK - * SFL_PCM_BOTH - * @param plugin The alsa plugin ( dmix , default , front , surround , ...) - */ - bool openDevice(int indexIn, int indexOut, int indexRing, int sampleRate, int frameSize , int stream, std::string plugin) ; - - DeviceList* getSinkList(void) { return &_sinkList; } - - DeviceList* getSourceList(void) { return &_sourceList; } - - void updateSinkList(void); - - void updateSourceList(void); - - bool inSinkList(std::string deviceName); - - bool inSourceList(std::string deviceName); - - void startStream(void); - - void stopStream(void); - - /** - * Query the capture device for number of bytes available in the hardware ring buffer - * @return int The number of bytes available - */ - int canGetMic(); - - /** - * Get data from the capture device - * @param buffer The buffer for data - * @param toCopy The number of bytes to get - * @return int The number of bytes acquired ( 0 if an error occured) - */ - int getMic(void *, int); - - static void overflow ( pa_stream* s, void* userdata ); - static void underflow ( pa_stream* s, void* userdata ); - static void stream_state_callback( pa_stream* s, void* user_data ); - static void context_state_callback( pa_context* c, void* user_data ); - // static void stream_suspended_callback ( pa_stream* s, void* userdata ); - - bool isCaptureActive (void){return true;} - - /** - * UNUSED in pulseaudio layer - */ - //std::vector<std::string> getSoundCardsInfo( int stream UNUSED ) { - //std::vector<std::string> tmp; - //return tmp; - //} - - /** - * Reduce volume of every audio applications connected to the same sink - */ - void reducePulseAppsVolume( void ); - - /** - * Restore the volume of every audio applications connected to the same sink to PA_VOLUME_NORM - */ - void restorePulseAppsVolume( void ); - - /** - * Set the volume of a sink. - * @param index The index of the stream - * @param channels The stream's number of channels - * @param volume The new volume (between 0 and 100) - */ - void setSinkVolume( int index, int channels, int volume ); - void setSourceVolume( int index, int channels, int volume ); - - void setPlaybackVolume( int volume ); - void setCaptureVolume( int volume ); - - /** - * Accessor - * @return AudioStream* The pointer on the playback AudioStream object - */ - AudioStream* getPlaybackStream(){ return playback;} - - /** - * Accessor - * @return AudioStream* The pointer on the record AudioStream object - */ - AudioStream* getRecordStream(){ return record;} - - /** - * Accessor - * @return AudioStream* The pointer on the ringtone AudioStream object - */ - AudioStream* getRingtoneStream(){ return ringtone;} - - int getSpkrVolume( void ) { return spkrVolume; } - void setSpkrVolume( int value ) { spkrVolume = value; } - - int getMicVolume( void ) { return micVolume; } - void setMicVolume( int value ) { micVolume = value; } - - void processPlaybackData( void ); - - void processCaptureData( void ); - - void processRingtoneData( void ); - - void processData(void); - - /** - * Get the echo canceller state - * @return true if echo cancel activated - */ - bool getEchoCancelState(void) { return AudioLayer::_echocancelstate; } - - /** - * Set the echo canceller state - * @param state true if echocancel active, false elsewhere - */ - void setEchoCancelState(bool state); - - /** - * Get the noise suppressor state - * @return true if noise suppressor activated - */ - bool getNoiseSuppressState(void) { return AudioLayer::_noisesuppressstate; } - - /** - * Set the noise suppressor state - * @param state true if noise suppressor active, false elsewhere - */ - void setNoiseSuppressState(bool state); - - private: - // Copy Constructor - PulseLayer(const PulseLayer& rh); - - // Assignment Operator - PulseLayer& operator=( const PulseLayer& rh); - - - /** - * Drop the pending frames and close the capture device - */ - void closeCaptureStream( void ); - - /** - * Write data from the ring buffer to the harware and read data from the hardware - */ - void readFromMic( void ); - void writeToSpeaker( void ); - void ringtoneToSpeaker( void ); - - /** - * Create the audio streams into the given context - * @param c The pulseaudio context - */ - bool createStreams( pa_context* c ); - - /** - * Drop the pending frames and close the playback device - */ - void closePlaybackStream( void ); - - /** - * Establishes the connection with the local pulseaudio server - */ - void connectPulseAudioServer( void ); - - /** - * Close the connection with the local pulseaudio server - */ - bool disconnectAudioStream( void ); - - /** - * Get some information about the pulseaudio server - */ - void serverinfo( void ); - - /** PulseAudio context and asynchronous loop */ - pa_context* context; - pa_threaded_mainloop* m; - - /** - * A stream object to handle the pulseaudio playback stream - */ - AudioStream* playback; - - /** - * A stream object to handle the pulseaudio capture stream - */ - AudioStream* record; - - /** - * A special stream object to handle specific playback stream for ringtone - */ - AudioStream* ringtone; - - /** Sample rate converter object */ - SamplerateConverter * _converter; - - bool is_started; - - int spkrVolume; - int micVolume; - - /* - ofstream *captureFile; - ofstream *captureRsmplFile; - ofstream *captureFilterFile; - */ - - DeviceList _sinkList; - - DeviceList _sourceList; - - // private: - -public: - - friend class AudioLayerTest; +class PulseLayer : public AudioLayer +{ + public: + PulseLayer (ManagerImpl* manager); + ~PulseLayer (void); + + void openLayer (void); + + bool closeLayer (void); + + /** + * Check if no devices are opened, otherwise close them. + * Then open the specified devices by calling the private functions open_device + * @param indexIn The number of the card chosen for capture + * @param indexOut The number of the card chosen for playback + * @param sampleRate The sample rate + * @param frameSize The frame size + * @param stream To indicate which kind of stream you want to open + * SFL_PCM_CAPTURE + * SFL_PCM_PLAYBACK + * SFL_PCM_BOTH + * @param plugin The alsa plugin ( dmix , default , front , surround , ...) + */ + bool openDevice (int indexIn, int indexOut, int indexRing, int sampleRate, int frameSize , int stream, std::string plugin) ; + + DeviceList* getSinkList (void) { + return &_sinkList; + } + + DeviceList* getSourceList (void) { + return &_sourceList; + } + + void updateSinkList (void); + + void updateSourceList (void); + + bool inSinkList (std::string deviceName); + + bool inSourceList (std::string deviceName); + + void startStream (void); + + void stopStream (void); + + /** + * Query the capture device for number of bytes available in the hardware ring buffer + * @return int The number of bytes available + */ + int canGetMic(); + + static void overflow (pa_stream* s, void* userdata); + static void underflow (pa_stream* s, void* userdata); + static void stream_state_callback (pa_stream* s, void* user_data); + static void context_state_callback (pa_context* c, void* user_data); + // static void stream_suspended_callback ( pa_stream* s, void* userdata ); + + bool isCaptureActive (void) { + return true; + } + + /** + * UNUSED in pulseaudio layer + */ + //std::vector<std::string> getSoundCardsInfo( int stream UNUSED ) { + //std::vector<std::string> tmp; + //return tmp; + //} + + /** + * Reduce volume of every audio applications connected to the same sink + */ + void reducePulseAppsVolume (void); + + /** + * Restore the volume of every audio applications connected to the same sink to PA_VOLUME_NORM + */ + void restorePulseAppsVolume (void); + + /** + * Set the volume of a sink. + * @param index The index of the stream + * @param channels The stream's number of channels + * @param volume The new volume (between 0 and 100) + */ + void setSinkVolume (int index, int channels, int volume); + void setSourceVolume (int index, int channels, int volume); + + void setPlaybackVolume (int volume); + void setCaptureVolume (int volume); + + /** + * Accessor + * @return AudioStream* The pointer on the playback AudioStream object + */ + AudioStream* getPlaybackStream() { + return playback; + } + + /** + * Accessor + * @return AudioStream* The pointer on the record AudioStream object + */ + AudioStream* getRecordStream() { + return record; + } + + /** + * Accessor + * @return AudioStream* The pointer on the ringtone AudioStream object + */ + AudioStream* getRingtoneStream() { + return ringtone; + } + + int getSpkrVolume (void) { + return spkrVolume; + } + void setSpkrVolume (int value) { + spkrVolume = value; + } + + int getMicVolume (void) { + return micVolume; + } + void setMicVolume (int value) { + micVolume = value; + } + + void processPlaybackData (void); + + void processCaptureData (void); + + void processRingtoneData (void); + + void processData (void); + + /** + * Get the echo canceller state + * @return true if echo cancel activated + */ + bool getEchoCancelState (void) { + return AudioLayer::_echocancelstate; + } + + /** + * Set the echo canceller state + * @param state true if echocancel active, false elsewhere + */ + void setEchoCancelState (bool state); + + /** + * Get the noise suppressor state + * @return true if noise suppressor activated + */ + bool getNoiseSuppressState (void) { + return AudioLayer::_noisesuppressstate; + } + + /** + * Set the noise suppressor state + * @param state true if noise suppressor active, false elsewhere + */ + void setNoiseSuppressState (bool state); + + private: + // Copy Constructor + PulseLayer (const PulseLayer& rh); + + // Assignment Operator + PulseLayer& operator= (const PulseLayer& rh); + + + /** + * Drop the pending frames and close the capture device + */ + void closeCaptureStream (void); + + /** + * Write data from the ring buffer to the harware and read data from the hardware + */ + void readFromMic (void); + void writeToSpeaker (void); + void ringtoneToSpeaker (void); + + /** + * Create the audio streams into the given context + * @param c The pulseaudio context + */ + bool createStreams (pa_context* c); + + /** + * Drop the pending frames and close the playback device + */ + void closePlaybackStream (void); + + /** + * Establishes the connection with the local pulseaudio server + */ + void connectPulseAudioServer (void); + + /** + * Close the connection with the local pulseaudio server + */ + bool disconnectAudioStream (void); + + /** + * Get some information about the pulseaudio server + */ + void serverinfo (void); + + /** PulseAudio context and asynchronous loop */ + pa_context* context; + pa_threaded_mainloop* m; + + /** + * A stream object to handle the pulseaudio playback stream + */ + AudioStream* playback; + + /** + * A stream object to handle the pulseaudio capture stream + */ + AudioStream* record; + + /** + * A special stream object to handle specific playback stream for ringtone + */ + AudioStream* ringtone; + + /** Sample rate converter object */ + SamplerateConverter * _converter; + + bool is_started; + + int spkrVolume; + int micVolume; + + /* + ofstream *captureFile; + ofstream *captureRsmplFile; + ofstream *captureFilterFile; + */ + + DeviceList _sinkList; + + DeviceList _sourceList; + + // private: + + int byteCounter; + + public: + + friend class AudioLayerTest; }; #endif // _PULSE_LAYER_H_ diff --git a/sflphone-common/src/audio/recordable.cpp b/sflphone-common/src/audio/recordable.cpp index 799bb814533b46d24905d101131f55fa0a3490c7..87c3f2b302aac7020335f3d25d5cbfdfa41f2c12 100644 --- a/sflphone-common/src/audio/recordable.cpp +++ b/sflphone-common/src/audio/recordable.cpp @@ -36,7 +36,7 @@ Recordable::Recordable() : recorder (&recAudio, Manager::instance().getMainBuffe FILE_TYPE fileType = FILE_WAV; SOUND_FORMAT soundFormat = INT16; - recAudio.setRecordingOption (fileType, soundFormat, 8000, Manager::instance().getConfigString (AUDIO, RECORD_PATH)); + recAudio.setRecordingOption (fileType, soundFormat, 8000, Manager::instance().audioPreference.getRecordpath()); } diff --git a/sflphone-common/src/audio/recordable.h b/sflphone-common/src/audio/recordable.h index 6b08db919674c1529653c343c367c08a3b0f2201..4ec7362afe78e39d127700d6632b423e43b9da03 100644 --- a/sflphone-common/src/audio/recordable.h +++ b/sflphone-common/src/audio/recordable.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> - * + * * 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 3 of the License, or @@ -10,7 +10,7 @@ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -33,52 +33,57 @@ #include "audiorecord.h" #include "audiorecorder.h" -class Recordable { +class Recordable +{ public: Recordable(); - ~Recordable(); + ~Recordable(); - /** - * Return recording state (true/false) - */ - bool isRecording(){ return recAudio.isRecording(); } + /** + * Return recording state (true/false) + */ + bool isRecording() { + return recAudio.isRecording(); + } - /** - * This method must be implemented for this interface as calls and conferences - * have different behavior. - */ - virtual bool setRecording() = 0; + /** + * This method must be implemented for this interface as calls and conferences + * have different behavior. + */ + virtual bool setRecording() = 0; - /** - * Stop recording - */ - void stopRecording(){ recAudio.stopRecording(); } + /** + * Stop recording + */ + void stopRecording() { + recAudio.stopRecording(); + } - /** - * Init the recording file name according to path specified in configuration - */ - void initRecFileName(); + /** + * Init the recording file name according to path specified in configuration + */ + void initRecFileName(); - /** - * Set recording sampling rate. - */ - void setRecordingSmplRate(int smplRate); + /** + * Set recording sampling rate. + */ + void setRecordingSmplRate (int smplRate); - virtual std::string getRecFileId() = 0; + virtual std::string getRecFileId() = 0; - // virtual std::string getFileName() = 0; + // virtual std::string getFileName() = 0; - // std::string getFileName() { return _filename; } + // std::string getFileName() { return _filename; } - /** - * An instance of audio recorder - */ - AudioRecord recAudio; + /** + * An instance of audio recorder + */ + AudioRecord recAudio; - AudioRecorder recorder; + AudioRecorder recorder; }; diff --git a/sflphone-common/src/audio/ringbuffer.cpp b/sflphone-common/src/audio/ringbuffer.cpp index cf7b9ecdfd38ae03cd9a0bef6c9dbaa52d31e757..8c2ecf44bbb6d3a59c4208c7421baa947893baa9 100644 --- a/sflphone-common/src/audio/ringbuffer.cpp +++ b/sflphone-common/src/audio/ringbuffer.cpp @@ -39,6 +39,7 @@ #include "ringbuffer.h" #include "global.h" +// corespond to 106 ms (about 5 rtp packets) #define MIN_BUFFER_SIZE 1280 int RingBuffer::count_rb = 0; @@ -178,8 +179,8 @@ RingBuffer::storeReadPointer (int pointer_value, CallID call_id) void RingBuffer::createReadPointer (CallID call_id) { - - _readpointer.insert (pair<CallID, int> (call_id, mEnd)); + if (!hasThisReadPointer (call_id)) + _readpointer.insert (pair<CallID, int> (call_id, mEnd)); } @@ -187,11 +188,10 @@ RingBuffer::createReadPointer (CallID call_id) void RingBuffer::removeReadPointer (CallID call_id) { + ReadPointer::iterator iter = _readpointer.find (call_id); - - _readpointer.erase (call_id); - - + if (iter != _readpointer.end()) + _readpointer.erase (iter); } diff --git a/sflphone-common/src/audio/ringbuffer.h b/sflphone-common/src/audio/ringbuffer.h index 6d5ad7d29e12a7d73a45cc0aaf0f54be486c8475..b52cd3417c21f953cd85aeb47ca936547a89f484 100644 --- a/sflphone-common/src/audio/ringbuffer.h +++ b/sflphone-common/src/audio/ringbuffer.h @@ -33,144 +33,149 @@ typedef map<CallID, int> ReadPointer; static CallID default_id = "audiolayer_id"; -class RingBuffer { - public: - /** - * Constructor - * @param size Size of the buffer to create - */ - RingBuffer(int size, CallID call_id = default_id); - - /** - * Destructor - */ - ~RingBuffer(); - - CallID getBufferId(){ return buffer_id; } - - /** - * Reset the counters to 0 for this read pointer - */ - void flush (CallID call_id = default_id); - - void flushAll(); - - /** - * Get read pointer coresponding to this call - */ - int getReadPointer(CallID call_id = default_id); - - /** - * Get the whole readpointer list for this ringbuffer - */ - ReadPointer* getReadPointerList() { return &_readpointer; } - - /** - * Return the smalest readpointer. Usefull to evaluate if ringbuffer is full - */ - int getSmallestReadPointer(); - - /** - * Move readpointer forward by pointer_value - */ - void storeReadPointer(int pointer_value, CallID call_id = default_id); - - /** - * Add a new readpointer for this ringbuffer - */ - void createReadPointer(CallID call_id = default_id); - - /** - * Remove a readpointer for this ringbuffer - */ - void removeReadPointer(CallID call_id = default_id); - - /** - * Test if readpointer coresponding to this call is still active - */ - bool hasThisReadPointer(CallID call_id); - - int getNbReadPointer(); - - /** - * To get how much space is available in the buffer to write in - * @return int The available size - */ - int AvailForPut (void); - - /** - * Write data in the ring buffer - * @param buffer Data to copied - * @param toCopy Number of bytes to copy - * @param volume The volume - * @return int Number of bytes copied - */ - int Put (void* buffer, int toCopy, unsigned short volume = 100); - - /** - * To get how much space is available in the buffer to read in - * @return int The available size - */ - int AvailForGet (CallID call_id = default_id); - - /** - * Get data in the ring buffer - * @param buffer Data to copied - * @param toCopy Number of bytes to copy - * @param volume The volume - * @return int Number of bytes copied - */ - int Get (void* buffer, int toCopy, unsigned short volume = 100, CallID call_id = default_id); - - /** - * Discard data from the buffer - * @param toDiscard Number of bytes to discard - * @return int Number of bytes discarded - */ - int Discard(int toDiscard, CallID call_id = default_id); - - /** - * Total length of the ring buffer - * @return int - */ - int putLen(); - - int getLen(CallID call_id = default_id); - - /** - * Debug function print mEnd, mStart, mBufferSize - */ - void debug(); - - private: - // Copy Constructor - RingBuffer(const RingBuffer& rh); - - // Assignment operator - RingBuffer& operator=(const RingBuffer& rh); - - /** Pointer on the first data */ - // int mStart; - /** Pointer on the last data */ - int mEnd; - /** Buffer size */ - int mBufferSize; - /** Data */ - samplePtr mBuffer; - - ReadPointer _readpointer; - - CallID buffer_id; - - public: - - friend class MainBufferTest; - - std::fstream *buffer_input_rec; - std::fstream *buffer_output_rec; - - static int count_rb; - +class RingBuffer +{ + public: + /** + * Constructor + * @param size Size of the buffer to create + */ + RingBuffer (int size, CallID call_id = default_id); + + /** + * Destructor + */ + ~RingBuffer(); + + CallID getBufferId() { + return buffer_id; + } + + /** + * Reset the counters to 0 for this read pointer + */ + void flush (CallID call_id = default_id); + + void flushAll(); + + /** + * Get read pointer coresponding to this call + */ + int getReadPointer (CallID call_id = default_id); + + /** + * Get the whole readpointer list for this ringbuffer + */ + ReadPointer* getReadPointerList() { + return &_readpointer; + } + + /** + * Return the smalest readpointer. Usefull to evaluate if ringbuffer is full + */ + int getSmallestReadPointer(); + + /** + * Move readpointer forward by pointer_value + */ + void storeReadPointer (int pointer_value, CallID call_id = default_id); + + /** + * Add a new readpointer for this ringbuffer + */ + void createReadPointer (CallID call_id = default_id); + + /** + * Remove a readpointer for this ringbuffer + */ + void removeReadPointer (CallID call_id = default_id); + + /** + * Test if readpointer coresponding to this call is still active + */ + bool hasThisReadPointer (CallID call_id); + + int getNbReadPointer(); + + /** + * To get how much space is available in the buffer to write in + * @return int The available size + */ + int AvailForPut (void); + + /** + * Write data in the ring buffer + * @param buffer Data to copied + * @param toCopy Number of bytes to copy + * @param volume The volume + * @return int Number of bytes copied + */ + int Put (void* buffer, int toCopy, unsigned short volume = 100); + + /** + * To get how much space is available in the buffer to read in + * @return int The available size + */ + int AvailForGet (CallID call_id = default_id); + + /** + * Get data in the ring buffer + * @param buffer Data to copied + * @param toCopy Number of bytes to copy + * @param volume The volume + * @return int Number of bytes copied + */ + int Get (void* buffer, int toCopy, unsigned short volume = 100, CallID call_id = default_id); + + /** + * Discard data from the buffer + * @param toDiscard Number of bytes to discard + * @return int Number of bytes discarded + */ + int Discard (int toDiscard, CallID call_id = default_id); + + /** + * Total length of the ring buffer + * @return int + */ + int putLen(); + + int getLen (CallID call_id = default_id); + + /** + * Debug function print mEnd, mStart, mBufferSize + */ + void debug(); + + private: + // Copy Constructor + RingBuffer (const RingBuffer& rh); + + // Assignment operator + RingBuffer& operator= (const RingBuffer& rh); + + /** Pointer on the first data */ + // int mStart; + /** Pointer on the last data */ + int mEnd; + /** Buffer size */ + int mBufferSize; + /** Data */ + samplePtr mBuffer; + + ReadPointer _readpointer; + + CallID buffer_id; + + public: + + friend class MainBufferTest; + + std::fstream *buffer_input_rec; + std::fstream *buffer_output_rec; + + static int count_rb; + }; diff --git a/sflphone-common/src/audio/samplerateconverter.h b/sflphone-common/src/audio/samplerateconverter.h index 3a20105fae5f5303bc940ae19a5c1e8dbb72a8e0..5645a64a4bc8d9a93a7123aa37c4764113e43515 100644 --- a/sflphone-common/src/audio/samplerateconverter.h +++ b/sflphone-common/src/audio/samplerateconverter.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * + * * 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 3 of the License, or @@ -10,7 +10,7 @@ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -36,75 +36,80 @@ #include "global.h" -class SamplerateConverter { - public: - /** Constructor */ - SamplerateConverter( void ); - SamplerateConverter( int freq , int fs ); - /** Destructor */ - ~SamplerateConverter( void ); - - /** - * Upsample from the samplerate1 to the samplerate2 - * @param data The data buffer - * @param SamplerateConverter1 The lower sample rate - * @param SamplerateConverter2 The higher sample rate - * @param nbSamples The number of samples to process - * @return int The number of samples after the operation - */ - int upsampleData( SFLDataFormat* dataIn , SFLDataFormat* dataOut , int samplerate1 , int samplerate2 , int nbSamples ); - - /** - * Downsample from the samplerate1 to the samplerate2 - * @param data The data buffer - * @param SamplerateConverter1 The lower sample rate - * @param SamplerateConverter2 The higher sample rate - * @param nbSamples The number of samples to process - * @return int The number of samples after the operation - */ - int downsampleData( SFLDataFormat* dataIn , SFLDataFormat* dataOut , int samplerate1 , int samplerate2 , int nbSamples ); - - int getFrequence( void ) { return _frequence; } - - int getFramesize( void ) { return _framesize; } - - /** - * Convert short table to floats for audio processing - * @param in the input (short) array - * @param out The resulting (float) array - * @param len The number of elements in both tables - */ - void Short2FloatArray (const short *in, float *out, int len); - - - private: - // Copy Constructor - SamplerateConverter(const SamplerateConverter& rh); - - // Assignment Operator - SamplerateConverter& operator=( const SamplerateConverter& rh); - - void init( void ); - - /** Audio layer caracteristics */ - int _frequence; - int _framesize; - - /** Downsampled/Upsampled float buffers for the mic data processing */ - float32* _floatBufferDownMic; - float32* _floatBufferUpMic; - /** libSamplerateConverter converter for outgoing voice */ - SRC_STATE* _src_state_mic; - - /** Downsampled/Upsampled float buffers for the speaker data processing */ - float32* _floatBufferDownSpkr; - float32* _floatBufferUpSpkr; - /** libSamplerateConverter converter for incoming voice */ - SRC_STATE* _src_state_spkr; - /** libSamplerateConverter error */ - int _src_err; - - +class SamplerateConverter +{ + public: + /** Constructor */ + SamplerateConverter (void); + SamplerateConverter (int freq , int fs); + /** Destructor */ + ~SamplerateConverter (void); + + /** + * Upsample from the samplerate1 to the samplerate2 + * @param data The data buffer + * @param SamplerateConverter1 The lower sample rate + * @param SamplerateConverter2 The higher sample rate + * @param nbSamples The number of samples to process + * @return int The number of samples after the operation + */ + int upsampleData (SFLDataFormat* dataIn , SFLDataFormat* dataOut , int samplerate1 , int samplerate2 , int nbSamples); + + /** + * Downsample from the samplerate1 to the samplerate2 + * @param data The data buffer + * @param SamplerateConverter1 The lower sample rate + * @param SamplerateConverter2 The higher sample rate + * @param nbSamples The number of samples to process + * @return int The number of samples after the operation + */ + int downsampleData (SFLDataFormat* dataIn , SFLDataFormat* dataOut , int samplerate1 , int samplerate2 , int nbSamples); + + int getFrequence (void) { + return _frequence; + } + + int getFramesize (void) { + return _framesize; + } + + /** + * Convert short table to floats for audio processing + * @param in the input (short) array + * @param out The resulting (float) array + * @param len The number of elements in both tables + */ + void Short2FloatArray (const short *in, float *out, int len); + + + private: + // Copy Constructor + SamplerateConverter (const SamplerateConverter& rh); + + // Assignment Operator + SamplerateConverter& operator= (const SamplerateConverter& rh); + + void init (void); + + /** Audio layer caracteristics */ + int _frequence; + int _framesize; + + /** Downsampled/Upsampled float buffers for the mic data processing */ + float32* _floatBufferDownMic; + float32* _floatBufferUpMic; + /** libSamplerateConverter converter for outgoing voice */ + SRC_STATE* _src_state_mic; + + /** Downsampled/Upsampled float buffers for the speaker data processing */ + float32* _floatBufferDownSpkr; + float32* _floatBufferUpSpkr; + /** libSamplerateConverter converter for incoming voice */ + SRC_STATE* _src_state_spkr; + /** libSamplerateConverter error */ + int _src_err; + + }; #endif //_SAMPLE_RATE_H diff --git a/sflphone-common/src/audio/sound/audiofile.cpp b/sflphone-common/src/audio/sound/audiofile.cpp index 97c0d49c88202db677bf2c93baff03407f5465f3..a176d4b7e9ad87656bd10b1127a0af4b6f75b36e 100644 --- a/sflphone-common/src/audio/sound/audiofile.cpp +++ b/sflphone-common/src/audio/sound/audiofile.cpp @@ -33,27 +33,27 @@ */ #include "audiofile.h" #include "audio/codecs/codecDescriptor.h" +#include "audio/samplerateconverter.h" #include <fstream> #include <math.h> #include <samplerate.h> #include <cstring> -AudioFile::AudioFile() - : AudioLoop(), - _filename(), - _codec (NULL), - _start (false) + +RawFile::RawFile() : _filename() + , _codec (NULL) { + AudioFile::_start = false; } -AudioFile::~AudioFile() +RawFile::~RawFile() { } // load file in mono format bool -AudioFile::loadFile (const std::string& filename, AudioCodec* codec , unsigned int sampleRate=8000) +RawFile::loadFile (const std::string& filename, AudioCodec* codec , unsigned int sampleRate=8000) { _codec = codec; @@ -175,3 +175,291 @@ AudioFile::loadFile (const std::string& filename, AudioCodec* codec , unsigned i return true; } + + + +WaveFile::WaveFile () : _byte_counter (0) + , _nb_channels (1) + , _file_size (0) + , _data_offset (0) + , _channels (0) + , _data_type (0) + , _file_rate (0) +{ + AudioFile::_start = false; +} + + +WaveFile::~WaveFile() +{ + _debug ("WaveFile: Destructor Called!"); +} + + + +bool WaveFile::openFile (const std::string& fileName, int audioSamplingRate) +{ + if (isFileExist (fileName)) { + openExistingWaveFile (fileName, audioSamplingRate); + } + + return true; +} + + + +bool WaveFile::closeFile() +{ + + _file_stream.close(); + + return true; + +} + + +bool WaveFile::isFileExist (const std::string& fileName) +{ + std::fstream fs (fileName.c_str(), std::ios_base::in); + + if (!fs) { + _debug ("WaveFile: file \"%s\" doesn't exist", fileName.c_str()); + return false; + } + + _debug ("WaveFile: File \"%s\" exists", fileName.c_str()); + return true; +} + + +bool WaveFile::isFileOpened() +{ + + if (_file_stream.is_open()) { + _debug ("WaveFile: file is openened"); + return true; + } else { + _debug ("WaveFile: file is not openend"); + return false; + } +} + + +bool WaveFile::openExistingWaveFile (const std::string& fileName, int audioSamplingRate) +{ + + _debug ("WaveFile: Opening %s", fileName.c_str()); + + _file_stream.open (fileName.c_str(), std::ios::in | std::ios::binary); + + char riff[4] = {}; + + _file_stream.read (riff, 4); + + if (strncmp ("RIFF", riff, 4) != 0) { + _debug ("WaveFile: File is not of RIFF format"); + return false; + } + + // Find the "fmt " chunk + char fmt[4] = {}; + + while (strncmp ("fmt ", fmt, 4) != 0) { + _file_stream.read (fmt, 4); + _debug ("Searching... \"fmt \""); + } + + SINT32 chunk_size; // fmt chunk size + unsigned short format_tag; // data compression tag + + _file_stream.read ( (char*) &chunk_size, 4); // Read fmt chunk size. + _file_stream.read ( (char*) &format_tag, 2); + + _debug ("WaveFile: Chunk size: %d", chunk_size); + _debug ("WaveFile: Format tag: %d", format_tag); + + + if (format_tag != 1) { // PCM = 1, FLOAT = 3 + _debug ("WaveFile: File contains an unsupported data format type"); + return false; + } + + + + // Get number of channels from the header. + SINT16 chan; + _file_stream.read ( (char*) &chan, 2); + + _channels = chan; + + _debug ("WaveFile: Channel %d", _channels); + + + // Get file sample rate from the header. + SINT32 srate; + _file_stream.read ( (char*) &srate, 4); + + _file_rate = (double) srate; + + _debug ("WaveFile: Sampling rate %d", srate); + + SINT32 avgb; + _file_stream.read ( (char*) &avgb, 4); + + _debug ("WaveFile: Average byte %d", avgb); + + SINT16 blockal; + _file_stream.read ( (char*) &blockal, 2); + + _debug ("WaveFile: Block alignment %d", blockal); + + + // Determine the data type + _data_type = 0; + + SINT16 dt; + _file_stream.read ( (char*) &dt, 2); + + _debug ("WaveFile: dt %d", dt); + + + if (format_tag == 1) { + if (dt == 8) + _data_type = 1; // SINT8; + else if (dt == 16) + _data_type = 2; // SINT16; + else if (dt == 32) + _data_type = 3; // SINT32; + } + /* + else if ( format_tag == 3 ) + { + if (temp == 32) + dataType_ = FLOAT32; + else if (temp == 64) + dataType_ = FLOAT64; + } + */ + else { + _debug ("WaveFile: File's bits per sample with is not supported"); + return false; + } + + + // Find the "data" chunk + char data[4] = {}; + + while (strncmp ("data", data, 4)) { + _file_stream.read (data, 4); + _debug ("Searching... data"); + } + + + // Sample rate converter initialized with 88200 sample long + int converterSamples = (srate > audioSamplingRate) ? srate : audioSamplingRate; + SamplerateConverter _converter (converterSamples, 2000); + + int nbSampleMax = 512; + + // Get length of data from the header. + SINT32 bytes; + _file_stream.read ( (char*) &bytes, 4); + + _debug ("WaveFile: data size in byte %d", bytes); + + _file_size = 8 * bytes / dt / _channels; // sample frames + + _debug ("WaveFile: data size in frame %ld", _file_size); + + // Should not be longer than a minute + if (_file_size > (unsigned int) (60*srate)) + _file_size = 60*srate; + + SFLDataFormat *tempBuffer = new SFLDataFormat[_file_size]; + + if (!tempBuffer) + return false; + + SFLDataFormat *tempBufferRsmpl = NULL; + + _file_stream.read ( (char *) tempBuffer, _file_size*sizeof (SFLDataFormat)); + + // compute size of final buffer + int nbSample; + + if (srate != audioSamplingRate) { + nbSample = (int) ( (float) _file_size * ( (float) audioSamplingRate / (float) srate)); + } else + nbSample = _file_size; + + int totalprocessed = 0; + + // require resampling + if (srate != audioSamplingRate) { + + // initialize remaining samples to process + int remainingSamples = _file_size; + + tempBufferRsmpl = new SFLDataFormat[nbSample]; + + if (!tempBufferRsmpl) + return false; + + SFLDataFormat *in = tempBuffer; + SFLDataFormat *out = tempBufferRsmpl; + + while (remainingSamples > 0) { + + int toProcess = remainingSamples > nbSampleMax ? nbSampleMax : remainingSamples; + int nbSamplesConverted = 0; + + if (srate < audioSamplingRate) { + nbSamplesConverted = _converter.upsampleData (in, out, srate, audioSamplingRate, toProcess); + } else if (srate > audioSamplingRate) { + nbSamplesConverted = _converter.downsampleData (in, out, audioSamplingRate, srate, toProcess); + } + + // nbSamplesConverted = nbSamplesConverted*2; + + in += toProcess; + out += nbSamplesConverted; + remainingSamples -= toProcess; + totalprocessed += nbSamplesConverted; + } + } + + // Init audio loop buffer info + _buffer = new SFLDataFormat[nbSample]; + + if (!_buffer) + return false; + + _size = nbSample; + _sampleRate = (int) audioSamplingRate; + + // Copy audio into audioloop + if (srate != audioSamplingRate) + memcpy ( (void *) _buffer, (void *) tempBufferRsmpl, nbSample*sizeof (SFLDataFormat)); + else + memcpy ( (void *) _buffer, (void *) tempBuffer, nbSample*sizeof (SFLDataFormat)); + + + _debug ("WaveFile: file successfully opened"); + + delete[] tempBuffer; + + if (tempBufferRsmpl) + delete[] tempBufferRsmpl; + + return true; + +} + + +bool WaveFile::loadFile (const std::string& filename, AudioCodec *codec , unsigned int sampleRate) +{ + + openFile (filename, sampleRate); + + return true; +} diff --git a/sflphone-common/src/audio/sound/audiofile.h b/sflphone-common/src/audio/sound/audiofile.h index 3b788341e670deaf70874ea5a7a14af28023167a..246808fdf8fbe4a8229102595ffff74e2601db42 100644 --- a/sflphone-common/src/audio/sound/audiofile.h +++ b/sflphone-common/src/audio/sound/audiofile.h @@ -2,10 +2,10 @@ * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Yan Morin <yan.morin@savoirfairelinux.com> * - * Inspired by tonegenerator of + * Inspired by tonegenerator of * Laurielle Lea <laurielle.lea@savoirfairelinux.com> (2004) * Inspired by ringbuffer of Audacity Project - * + * * 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 3 of the License, or @@ -34,70 +34,156 @@ #ifndef __AUDIOFILE_H__ #define __AUDIOFILE_H__ +#include <fstream> + #include "audio/audioloop.h" #include "audio/codecs/audiocodec.h" #include "audio/codecs/codecDescriptor.h" + +/** + * @brief Abstract interface for file readers + */ +class AudioFile : public AudioLoop +{ + public: + + /** + * Load a sound file in memory + * @param filename The absolute path to the file + * @param codec The codec to decode and encode it + * @param sampleRate The sample rate to read it + * @return bool True on success + */ + virtual bool loadFile (const std::string& filename, AudioCodec *codec , unsigned int sampleRate) = 0; + + /** + * Start the sound file + */ + void start() { + _start = true; + } + + /** + * Stop the sound file + */ + void stop() { + _start = false; + } + + /** + * Tells whether or not the file is playing + * @return bool True if yes + * false otherwise + */ + bool isStarted() { + return _start; + } + + protected: + + /** start or not */ + bool _start; +}; + + + /** * @file audiofile.h * @brief A class to manage sound files */ -class AudioFile : public AudioLoop +class RawFile : public AudioFile +{ + public: + /** + * Constructor + */ + RawFile(); + + /** + * Destructor + */ + ~RawFile(); + + + /** + * Load a sound file in memory + * @param filename The absolute path to the file + * @param codec The codec to decode and encode it + * @param sampleRate The sample rate to read it + * @return bool True on success + */ + virtual bool loadFile (const std::string& filename, AudioCodec *codec , unsigned int sampleRate); + + private: + // Copy Constructor + RawFile (const RawFile& rh); + + // Assignment Operator + RawFile& operator= (const RawFile& rh); + + /** The absolute path to the sound file */ + std::string _filename; + + /** Your preferred codec */ + AudioCodec* _codec; +}; + + +class WaveFile : public AudioFile { -public: - /** - * Constructor - */ - AudioFile(); - - /** - * Destructor - */ - ~AudioFile(); - - - /** - * Load a sound file in memory - * @param filename The absolute path to the file - * @param codec The codec to decode and encode it - * @param sampleRate The sample rate to read it - * @return bool True on success - */ - bool loadFile(const std::string& filename, AudioCodec *codec , unsigned int sampleRate); - - /** - * Start the sound file - */ - void start() { _start = true; } - - /** - * Stop the sound file - */ - void stop() { _start = false; } - - /** - * Tells whether or not the file is playing - * @return bool True if yes - * false otherwise - */ - bool isStarted() { return _start; } - -private: - // Copy Constructor - AudioFile(const AudioFile& rh); - - // Assignment Operator - AudioFile& operator=( const AudioFile& rh); - - /** The absolute path to the sound file */ - std::string _filename; - - /** Your preferred codec */ - AudioCodec* _codec; - - /** Start or not */ - bool _start; + + public: + + WaveFile (); + + ~WaveFile(); + + bool openFile (const std::string& fileName, int audioSamplingRate); + + bool closeFile(); + + bool isFileExist (const std::string& fileName); + + bool isFileOpened(); + + /** + * Load a sound file in memory + * @param filename The absolute path to the file + * @param codec The codec to decode and encode it + * @param sampleRate The sample rate to read it + * @return bool True on success + */ + virtual bool loadFile (const std::string& filename, AudioCodec *codec , unsigned int sampleRate); + + private: + + bool setWaveFile(); + + bool openExistingWaveFile (const std::string& fileName, int audioSamplingRate); + + SOUND_FORMAT _snd_format; + + long _byte_counter; + + int _nb_channels; + + unsigned long _file_size; + + unsigned long _data_offset; + + SINT16 _channels; + + SOUND_FORMAT _data_type; + + double _file_rate; + + std::fstream _file_stream; + + std::string _fileName; + }; -#endif // __AUDIOFILE_H__ +#endif + diff --git a/sflphone-common/src/audio/sound/dtmf.h b/sflphone-common/src/audio/sound/dtmf.h index 155eca3a412d02457810ebf050a80644468378dd..41609cec66765b62c462750962ac93ba298b03b2 100644 --- a/sflphone-common/src/audio/sound/dtmf.h +++ b/sflphone-common/src/audio/sound/dtmf.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author : Yan Morin <yan.morin@savoirfairelinux.com> - * Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com> + * Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com> * * Portions Copyright (c) 2000 Billy Biggs <bbiggs@div8.net> * Portions Copyright (c) 2004 Wirlab <kphone@wirlab.net> @@ -42,36 +42,37 @@ * @file dtmf.h * @brief DMTF library to generate a dtmf sample */ -class DTMF { - public: - /** - * Create a new DTMF. - * @param sampleRate frequency of the sample (ex: 8000 hz) - */ - DTMF (unsigned int sampleRate); - - /** - * Destructor - */ - ~DTMF (void); +class DTMF +{ + public: + /** + * Create a new DTMF. + * @param sampleRate frequency of the sample (ex: 8000 hz) + */ + DTMF (unsigned int sampleRate); - /** - * Start the done for th given dtmf - * @param code The DTMF code - */ - void startTone(char code); - - /** - * Copy the sound inside the sampling* buffer - * @param buffer : a SFLDataFormat* buffer - * @param n : The size to generate - */ - bool generateDTMF (SFLDataFormat* buffer, size_t n); + /** + * Destructor + */ + ~DTMF (void); - char currentTone; - char newTone; + /** + * Start the done for th given dtmf + * @param code The DTMF code + */ + void startTone (char code); - DTMFGenerator dtmfgenerator; + /** + * Copy the sound inside the sampling* buffer + * @param buffer : a SFLDataFormat* buffer + * @param n : The size to generate + */ + bool generateDTMF (SFLDataFormat* buffer, size_t n); + + char currentTone; + char newTone; + + DTMFGenerator dtmfgenerator; }; #endif // __KEY_DTMF_H_ diff --git a/sflphone-common/src/audio/sound/dtmfgenerator.h b/sflphone-common/src/audio/sound/dtmfgenerator.h index 5fa095f0fc0edff600a5171f8300e4624575cd3e..84423b7853f0245f1f56ad9a336d66f872d74917 100644 --- a/sflphone-common/src/audio/sound/dtmfgenerator.h +++ b/sflphone-common/src/audio/sound/dtmfgenerator.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Yan Morin <yan.morin@savoirfairelinux.com> - * Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com> + * Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com> * * Portions (c) 2003 iptel.org * @@ -9,12 +9,12 @@ * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 3 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 Library General Public * License for more details. - * + * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, @@ -49,113 +49,113 @@ */ class DTMFException : public std::exception { - private: - - /** Message */ - const char* reason; - public: - /** - * Constructor - * @param _reason An error message - */ - DTMFException(const char* _reason) throw(); - - /** - * Destructor - */ - virtual ~DTMFException() throw(); -/* - // Copy Constructor - DTMFException(const DTMFException& rh) throw(); - - // Assignment Operator - DTMFException& operator=( const DTMFException& rh) throw(); -*/ - /** - * @return const char* The error - */ - virtual const char* what() const throw(); + private: + + /** Message */ + const char* reason; + public: + /** + * Constructor + * @param _reason An error message + */ + DTMFException (const char* _reason) throw(); + + /** + * Destructor + */ + virtual ~DTMFException() throw(); + /* + // Copy Constructor + DTMFException(const DTMFException& rh) throw(); + + // Assignment Operator + DTMFException& operator=( const DTMFException& rh) throw(); + */ + /** + * @return const char* The error + */ + virtual const char* what() const throw(); }; /* * @file dtmfgenerator.h * @brief DTMF Tone Generator */ -class DTMFGenerator +class DTMFGenerator { - private: - /** Struct to handle a DTMF */ - struct DTMFTone { - unsigned char code; /** Code of the tone */ - int lower; /** Lower frequency */ - int higher; /** Higher frequency */ - }; - - /** State of the DTMF generator */ - struct DTMFState { - unsigned int offset; /** Offset in the sample currently being played */ - SFLDataFormat* sample; /** Currently generated code */ - }; - - /** State of the DTMF generator */ - DTMFState state; - - /** The different kind of tones */ - static const DTMFTone tones[NUM_TONES]; - - /** Generated samples */ - SFLDataFormat* samples[NUM_TONES]; - - /** Sampling rate of generated dtmf */ - int _sampleRate; - - /** A tone object */ - Tone tone; - - public: - /** - * DTMF Generator contains frequency of each keys - * and can build one DTMF. - * @param sampleRate frequency of the sample (ex: 8000 hz) - */ - DTMFGenerator(unsigned int sampleRate); - - /** - * Destructor - */ - ~DTMFGenerator(); - - - // Copy Constructor - DTMFGenerator(const DTMFGenerator& rh); - - // Assignment Operator - DTMFGenerator& operator=( const DTMFGenerator& rh); - - /* - * Get n samples of the signal of code code - * @param buffer a SFLDataFormat pointer to an allocated buffer - * @param n number of sampling to get, should be lower or equal to buffer size - * @param code dtmf code to get sound - */ - void getSamples(SFLDataFormat* buffer, size_t n, unsigned char code) throw (DTMFException); - - /* - * Get next n samples (continues where previous call to - * genSample or genNextSamples stopped - * @param buffer a SFLDataFormat pointer to an allocated buffer - * @param n number of sampling to get, should be lower or equal to buffer size - */ - void getNextSamples(SFLDataFormat* buffer, size_t n) throw (DTMFException); - - private: - - /** - * Generate samples for a specific dtmf code - * @param code The code - * @return SFLDataFormat* The generated data - */ - SFLDataFormat* generateSample(unsigned char code) throw (DTMFException); + private: + /** Struct to handle a DTMF */ + struct DTMFTone { + unsigned char code; /** Code of the tone */ + int lower; /** Lower frequency */ + int higher; /** Higher frequency */ + }; + + /** State of the DTMF generator */ + struct DTMFState { + unsigned int offset; /** Offset in the sample currently being played */ + SFLDataFormat* sample; /** Currently generated code */ + }; + + /** State of the DTMF generator */ + DTMFState state; + + /** The different kind of tones */ + static const DTMFTone tones[NUM_TONES]; + + /** Generated samples */ + SFLDataFormat* samples[NUM_TONES]; + + /** Sampling rate of generated dtmf */ + int _sampleRate; + + /** A tone object */ + Tone tone; + + public: + /** + * DTMF Generator contains frequency of each keys + * and can build one DTMF. + * @param sampleRate frequency of the sample (ex: 8000 hz) + */ + DTMFGenerator (unsigned int sampleRate); + + /** + * Destructor + */ + ~DTMFGenerator(); + + + // Copy Constructor + DTMFGenerator (const DTMFGenerator& rh); + + // Assignment Operator + DTMFGenerator& operator= (const DTMFGenerator& rh); + + /* + * Get n samples of the signal of code code + * @param buffer a SFLDataFormat pointer to an allocated buffer + * @param n number of sampling to get, should be lower or equal to buffer size + * @param code dtmf code to get sound + */ + void getSamples (SFLDataFormat* buffer, size_t n, unsigned char code) throw (DTMFException); + + /* + * Get next n samples (continues where previous call to + * genSample or genNextSamples stopped + * @param buffer a SFLDataFormat pointer to an allocated buffer + * @param n number of sampling to get, should be lower or equal to buffer size + */ + void getNextSamples (SFLDataFormat* buffer, size_t n) throw (DTMFException); + + private: + + /** + * Generate samples for a specific dtmf code + * @param code The code + * @return SFLDataFormat* The generated data + */ + SFLDataFormat* generateSample (unsigned char code) throw (DTMFException); }; #endif // DTMFGENERATOR_H diff --git a/sflphone-common/src/audio/sound/tone.h b/sflphone-common/src/audio/sound/tone.h index cc813603c7df5f8eba10a2203137e6d86bc40e4e..8ce8359774a36477412ae218d2eb7d959139ea3f 100644 --- a/sflphone-common/src/audio/sound/tone.h +++ b/sflphone-common/src/audio/sound/tone.h @@ -2,9 +2,9 @@ * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Yan Morin <yan.morin@savoirfairelinux.com> * - * Inspired by tonegenerator of + * Inspired by tonegenerator of * Laurielle Lea <laurielle.lea@savoirfairelinux.com> (2004) - * + * * 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 3 of the License, or @@ -45,65 +45,66 @@ * @file tone.h * @brief Tone sample (dial, busy, ring, congestion) */ -class Tone : public AudioLoop { -public: - /** - * Constructor - * @param definition String that contain frequency/time of the tone - * @param sampleRate SampleRating of audio tone - */ - Tone(const std::string& definition, unsigned int sampleRate); - - /** - * Destructor - */ - ~Tone(); - - /** The different kind of tones */ - enum TONEID { - TONE_DIALTONE = 0, - TONE_BUSY, - TONE_RINGTONE, - TONE_CONGESTION, - TONE_NULL - }; - - /** - * Add a simple or double sin to the buffer, it double the sin in stereo - * @param buffer The data - * @param frequency1 The first frequency - * @param frequency2 The second frequency - * @param nb are the number of int16 (mono) to generate - * by example nb=5 generate 10 int16, 5 for the left, 5 for the right - */ - void genSin(SFLDataFormat* buffer, int frequency1, int frequency2, int nb); - - /** - * - */ - void fillWavetable(void); - - /** - * - */ - double interpolate(double x); - - -private: - - /** - * allocate the memory with the definition - * @param definition String that contain frequency/time of the tone. - */ - void genBuffer(const std::string& definition); - - /** Sample rate */ - unsigned int _sampleRate; - - double _wavetable[TABLE_LENGTH]; - - double _xhigher; - double _xlower; +class Tone : public AudioLoop +{ + public: + /** + * Constructor + * @param definition String that contain frequency/time of the tone + * @param sampleRate SampleRating of audio tone + */ + Tone (const std::string& definition, unsigned int sampleRate); + + /** + * Destructor + */ + ~Tone(); + + /** The different kind of tones */ + enum TONEID { + TONE_DIALTONE = 0, + TONE_BUSY, + TONE_RINGTONE, + TONE_CONGESTION, + TONE_NULL + }; + + /** + * Add a simple or double sin to the buffer, it double the sin in stereo + * @param buffer The data + * @param frequency1 The first frequency + * @param frequency2 The second frequency + * @param nb are the number of int16 (mono) to generate + * by example nb=5 generate 10 int16, 5 for the left, 5 for the right + */ + void genSin (SFLDataFormat* buffer, int frequency1, int frequency2, int nb); + + /** + * + */ + void fillWavetable (void); + + /** + * + */ + double interpolate (double x); + + + private: + + /** + * allocate the memory with the definition + * @param definition String that contain frequency/time of the tone. + */ + void genBuffer (const std::string& definition); + + /** Sample rate */ + unsigned int _sampleRate; + + double _wavetable[TABLE_LENGTH]; + + double _xhigher; + double _xlower; }; #endif // __TONE_H__ diff --git a/sflphone-common/src/audio/sound/tonelist.h b/sflphone-common/src/audio/sound/tonelist.h index 41c9e5f48c38c26995b701f3f84d2642e3d6dfbc..210a74c7938e821bd5cbc99ddaf5966d3a646814 100644 --- a/sflphone-common/src/audio/sound/tonelist.h +++ b/sflphone-common/src/audio/sound/tonelist.h @@ -2,9 +2,9 @@ * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Yan Morin <yan.morin@savoirfairelinux.com> * - * Inspired by tonegenerator of + * Inspired by tonegenerator of * Laurielle Lea <laurielle.lea@savoirfairelinux.com> (2004) - * + * * 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 3 of the License, or @@ -40,98 +40,102 @@ * @file tonelist.h * @brief Manages the different kind of tones according to the country */ -class ToneList { -public: - /** - * Constructor - */ - ToneList(); - - /** - * Destructor - */ - ~ToneList(); - - - /** Countries */ - enum COUNTRYID { - ZID_NORTH_AMERICA = 0, - ZID_FRANCE, - ZID_AUSTRALIA, - ZID_UNITED_KINGDOM, - ZID_SPAIN, - ZID_ITALY, - ZID_JAPAN - }; - - /** - * Get the string definition of a tone - * return the default country or default tone if id are invalid - * @param countryId The country Id, see ToneList constructor for the list - * @param toneId The toneId - * @return std::string A string definition of the tone - */ - std::string getDefinition(COUNTRYID countryId, Tone::TONEID toneId); - - /** - * Get the country id associate to a country name - * return the default country id if not found - * The default tone/country are set inside the ToneList constructor - * @param countryName countryName, see the ToneList constructor list - * @return COUNTRYID Country Id or default Id - */ - COUNTRYID getCountryId(const std::string& countryName); - - /** @return int The number of tones */ - int getNbTone() { return _nbTone; } - -private: - - // Copy Constructor - ToneList(const ToneList& rh); - - // Assignment Operator - ToneList& operator=( const ToneList& rh); - - void initToneDefinition(); - std::string _toneZone[TONE_NBCOUNTRY][TONE_NBTONE]; - int _nbTone; - int _nbCountry; - COUNTRYID _defaultCountryId; +class ToneList +{ + public: + /** + * Constructor + */ + ToneList(); + + /** + * Destructor + */ + ~ToneList(); + + + /** Countries */ + enum COUNTRYID { + ZID_NORTH_AMERICA = 0, + ZID_FRANCE, + ZID_AUSTRALIA, + ZID_UNITED_KINGDOM, + ZID_SPAIN, + ZID_ITALY, + ZID_JAPAN + }; + + /** + * Get the string definition of a tone + * return the default country or default tone if id are invalid + * @param countryId The country Id, see ToneList constructor for the list + * @param toneId The toneId + * @return std::string A string definition of the tone + */ + std::string getDefinition (COUNTRYID countryId, Tone::TONEID toneId); + + /** + * Get the country id associate to a country name + * return the default country id if not found + * The default tone/country are set inside the ToneList constructor + * @param countryName countryName, see the ToneList constructor list + * @return COUNTRYID Country Id or default Id + */ + COUNTRYID getCountryId (const std::string& countryName); + + /** @return int The number of tones */ + int getNbTone() { + return _nbTone; + } + + private: + + // Copy Constructor + ToneList (const ToneList& rh); + + // Assignment Operator + ToneList& operator= (const ToneList& rh); + + void initToneDefinition(); + std::string _toneZone[TONE_NBCOUNTRY][TONE_NBTONE]; + int _nbTone; + int _nbCountry; + COUNTRYID _defaultCountryId; }; /** * @author Yan Morin <yan.morin@savoirfairelinux.com> */ -class TelephoneTone { -public: - /** Initialize the toneList and set the current tone to null */ - TelephoneTone(const std::string& countryName, unsigned int sampleRate); - ~TelephoneTone(); - - - /** send TONE::ZT_TONE_NULL to stop the playing */ - void setCurrentTone(Tone::TONEID toneId); - - /** - * @return the currentTone after setting it with setCurrentTone - * 0 if the current tone is null - */ - Tone* getCurrentTone(); - - /** @return true if you should play the tone (CurrentTone is not NULL) */ - bool shouldPlay(); - -private: - // Copy Constructor - TelephoneTone(const TelephoneTone& rh); - - // Assignment Operator - TelephoneTone& operator=( const TelephoneTone& rh); - - Tone* _tone[TONE_NBTONE]; - Tone::TONEID _currentTone; - ToneList _toneList; +class TelephoneTone +{ + public: + /** Initialize the toneList and set the current tone to null */ + TelephoneTone (const std::string& countryName, unsigned int sampleRate); + ~TelephoneTone(); + + + /** send TONE::ZT_TONE_NULL to stop the playing */ + void setCurrentTone (Tone::TONEID toneId); + + /** + * @return the currentTone after setting it with setCurrentTone + * 0 if the current tone is null + */ + Tone* getCurrentTone(); + + /** @return true if you should play the tone (CurrentTone is not NULL) */ + bool shouldPlay(); + + private: + // Copy Constructor + TelephoneTone (const TelephoneTone& rh); + + // Assignment Operator + TelephoneTone& operator= (const TelephoneTone& rh); + + Tone* _tone[TONE_NBTONE]; + Tone::TONEID _currentTone; + ToneList _toneList; }; #endif diff --git a/sflphone-common/src/audio/speexechocancel.cpp b/sflphone-common/src/audio/speexechocancel.cpp index 40017ed7bc728ab6a8664ebb81191fe903bebd2d..a85a4caccbefae407483d480746b72202beef973 100644 --- a/sflphone-common/src/audio/speexechocancel.cpp +++ b/sflphone-common/src/audio/speexechocancel.cpp @@ -100,7 +100,7 @@ void SpeexEchoCancel::putData (SFLDataFormat *inputData, int nbBytes) // speex_echo_playback(_echoState, inputData); } -void SpeexEchoCancel::process (SFLDataFormat *data, int nbBytes) {} +void SpeexEchoCancel::process (SFLDataFormat *data UNUSED, int nbBytes UNUSED) {} int SpeexEchoCancel::process (SFLDataFormat *inputData, SFLDataFormat *outputData, int nbBytes) { @@ -158,10 +158,7 @@ int SpeexEchoCancel::process (SFLDataFormat *inputData, SFLDataFormat *outputDat return nbFrame * FRAME_SIZE; } -void SpeexEchoCancel::process (SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes) +void SpeexEchoCancel::process (SFLDataFormat *micData UNUSED, SFLDataFormat *spkrData UNUSED, SFLDataFormat *outputData UNUSED, int nbBytes UNUSED) { - - // speex_echo_cancellation(_echoState, micData, spkrData, outputData); - } diff --git a/sflphone-common/src/audio/speexechocancel.h b/sflphone-common/src/audio/speexechocancel.h index 45628e14af81c7eecf9fb8b66f92bbf03f897060..fd37cf2ae177360443d8bafafc3f6e5669ab4bb1 100644 --- a/sflphone-common/src/audio/speexechocancel.h +++ b/sflphone-common/src/audio/speexechocancel.h @@ -26,60 +26,61 @@ #include "ringbuffer.h" -class SpeexEchoCancel : public Algorithm { +class SpeexEchoCancel : public Algorithm +{ - public: + public: - SpeexEchoCancel(); + SpeexEchoCancel(); - ~SpeexEchoCancel(); + ~SpeexEchoCancel(); - virtual void reset(void); + virtual void reset (void); - /** - * Add speaker data into internal buffer - * \param inputData containing far-end voice data to be sent to speakers - */ - virtual void putData(SFLDataFormat *inputData, int nbBytes); + /** + * Add speaker data into internal buffer + * \param inputData containing far-end voice data to be sent to speakers + */ + virtual void putData (SFLDataFormat *inputData, int nbBytes); - /** - * Unused - */ - virtual void process(SFLDataFormat *data, int nbBytes); + /** + * Unused + */ + virtual void process (SFLDataFormat *data, int nbBytes); - /** - * Perform echo cancellation using internal buffers - * \param inputData containing mixed echo and voice data - * \param outputData containing - */ - virtual int process(SFLDataFormat *inputData, SFLDataFormat *outputData, int nbBytes); + /** + * Perform echo cancellation using internal buffers + * \param inputData containing mixed echo and voice data + * \param outputData containing + */ + virtual int process (SFLDataFormat *inputData, SFLDataFormat *outputData, int nbBytes); - /** - * Perform echo cancellation, application must provide its own buffer - * \param micData containing mixed echo and voice data - * \param spkrData containing far-end voice data to be sent to speakers - * \param outputData containing the processed data - */ - virtual void process(SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes); + /** + * Perform echo cancellation, application must provide its own buffer + * \param micData containing mixed echo and voice data + * \param spkrData containing far-end voice data to be sent to speakers + * \param outputData containing the processed data + */ + virtual void process (SFLDataFormat *micData, SFLDataFormat *spkrData, SFLDataFormat *outputData, int nbBytes); - private: + private: - SpeexEchoState *_echoState; + SpeexEchoState *_echoState; - SpeexPreprocessState *_preState; + SpeexPreprocessState *_preState; - RingBuffer *_micData; - RingBuffer *_spkrData; + RingBuffer *_micData; + RingBuffer *_spkrData; - bool _spkrStoped; + bool _spkrStoped; - SFLDataFormat _tmpSpkr[5000]; - SFLDataFormat _tmpMic[5000]; - SFLDataFormat _tmpOut[5000]; + SFLDataFormat _tmpSpkr[5000]; + SFLDataFormat _tmpMic[5000]; + SFLDataFormat _tmpOut[5000]; - ofstream *micFile; - ofstream *spkrFile; - ofstream *echoFile; + ofstream *micFile; + ofstream *spkrFile; + ofstream *echoFile; }; #endif diff --git a/sflphone-common/src/call.cpp b/sflphone-common/src/call.cpp index 51a3d4546360ac7e7ac3a970d8d65cddb18a61f4..040d90c74ca1a3a69bb5897cb1c3ef947f7ae3a7 100644 --- a/sflphone-common/src/call.cpp +++ b/sflphone-common/src/call.cpp @@ -189,6 +189,8 @@ Call::isAudioStarted() bool Call::setRecording() { + _debug ("Call: Set recording"); + bool recordStatus = Recordable::recAudio.isRecording(); Recordable::recAudio.setRecording(); @@ -196,16 +198,21 @@ Call::setRecording() // Start recording if (!recordStatus) { + _debug ("Call: Call not recording yet, set ringbuffers"); + MainBuffer *mbuffer = Manager::instance().getMainBuffer(); CallID process_id = Recordable::recorder.getRecorderID(); mbuffer->bindHalfDuplexOut (process_id, _id); mbuffer->bindHalfDuplexOut (process_id); + Recordable::recorder.start(); } // Stop recording else { + _debug ("Call: Stop recording"); + MainBuffer *mbuffer = Manager::instance().getMainBuffer(); CallID process_id = Recordable::recorder.getRecorderID(); @@ -216,7 +223,5 @@ Call::setRecording() Manager::instance().getMainBuffer()->stateInfo(); - Recordable::recorder.start(); - return recordStatus; } diff --git a/sflphone-common/src/call.h b/sflphone-common/src/call.h index 713f23e5609637c9c292c84e7a6d7c453dea1da7..f7fb935f167d4320fdc703c729bd3fcb67bc3a52 100644 --- a/sflphone-common/src/call.h +++ b/sflphone-common/src/call.h @@ -42,14 +42,15 @@ #define CallConfigNULL NULL -/* - * @file call.h +/* + * @file call.h * @brief A call is the base class for protocol-based calls */ typedef std::string CallID; -class Call: public Recordable{ +class Call: public Recordable +{ public: /** @@ -83,84 +84,103 @@ class Call: public Recordable{ * @param id Unique identifier of the call * @param type set definitely this call as incoming/outgoing */ - Call(const CallID& id, Call::CallType type); + Call (const CallID& id, Call::CallType type); virtual ~Call(); - /** + /** * Return a reference on the call id * @return call id */ - CallID& getCallId() {return _id; } + CallID& getCallId() { + return _id; + } - /** - * Return a reference on the conference id - * @return call id - */ - CallID& getConfId() {return _confID; } + /** + * Return a reference on the conference id + * @return call id + */ + CallID& getConfId() { + return _confID; + } - void setConfId(CallID id) {_confID = id; } + void setConfId (CallID id) { + _confID = id; + } - inline CallType getCallType (void) - { + inline CallType getCallType (void) { return _type; } - /** + /** * Set the peer number (destination on outgoing) * not protected by mutex (when created) * @param number peer number */ - void setPeerNumber(const std::string& number) { _peerNumber = number; } + void setPeerNumber (const std::string& number) { + _peerNumber = number; + } - /** + /** * Get the peer number (destination on outgoing) * not protected by mutex (when created) * @return std::string The peer number */ - const std::string& getPeerNumber() { return _peerNumber; } + const std::string& getPeerNumber() { + return _peerNumber; + } - /** + /** * Set the peer name (caller in ingoing) * not protected by mutex (when created) * @param name The peer name */ - void setPeerName(const std::string& name) { _peerName = name; } + void setPeerName (const std::string& name) { + _peerName = name; + } - /** + /** * Get the peer name (caller in ingoing) * not protected by mutex (when created) * @return std::string The peer name */ - const std::string& getPeerName() { return _peerName; } + const std::string& getPeerName() { + return _peerName; + } - /** - * Set the display name (caller in ingoing) - * not protected by mutex (when created) - * @return std::string The peer display name - */ - void setDisplayName(const std::string& name) { _displayName = name; } + /** + * Set the display name (caller in ingoing) + * not protected by mutex (when created) + * @return std::string The peer display name + */ + void setDisplayName (const std::string& name) { + _displayName = name; + } - /** - * Get the peer display name (caller in ingoing) - * not protected by mutex (when created) - * @return std::string The peer name - */ - const std::string& getDisplayName() { return _displayName; } + /** + * Get the peer display name (caller in ingoing) + * not protected by mutex (when created) + * @return std::string The peer name + */ + const std::string& getDisplayName() { + return _displayName; + } /** * Tell if the call is incoming * @return true if yes * false otherwise */ - bool isIncoming() { return (_type == Incoming) ? true : false; } + bool isIncoming() { + return (_type == Incoming) ? true : false; + } - /** + /** * Set the connection state of the call (protected by mutex) * @param state The connection state */ - void setConnectionState(ConnectionState state); + void setConnectionState (ConnectionState state); - /** + /** * Get the connection state of the call (protected by mutex) * @return ConnectionState The connection state */ @@ -170,26 +190,30 @@ class Call: public Recordable{ * Set the state of the call (protected by mutex) * @param state The call state */ - void setState(CallState state); + void setState (CallState state); - /** + /** * Get the call state of the call (protected by mutex) * @return CallState The call state */ CallState getState(); - + std::string getStateStr (); - void setCallConfiguration (Call::CallConfiguration callConfig) { _callConfig = callConfig; } - - Call::CallConfiguration getCallConfiguration (void) { return _callConfig; } - + void setCallConfiguration (Call::CallConfiguration callConfig) { + _callConfig = callConfig; + } + + Call::CallConfiguration getCallConfiguration (void) { + return _callConfig; + } + /** * Set the audio start boolean (protected by mutex) * @param start true if we start the audio * false otherwise */ - void setAudioStart(bool start); + void setAudioStart (bool start); /** * Tell if the audio is started (protected by mutex) @@ -198,47 +222,59 @@ class Call: public Recordable{ */ bool isAudioStarted(); - /** - * Set my IP [not protected] + /** + * Set my IP [not protected] * @param ip The local IP address */ - void setLocalIp(const std::string& ip) { _localIPAddress = ip; } + void setLocalIp (const std::string& ip) { + _localIPAddress = ip; + } - /** + /** * Set local audio port, as seen by me [not protected] * @param port The local audio port */ - void setLocalAudioPort(unsigned int port) { _localAudioPort = port;} + void setLocalAudioPort (unsigned int port) { + _localAudioPort = port; + } - /** + /** * Set the audio port that remote will see. * @param port The external audio port */ - void setLocalExternAudioPort(unsigned int port) { _localExternalAudioPort = port; } + void setLocalExternAudioPort (unsigned int port) { + _localExternalAudioPort = port; + } - /** - * Return the audio port seen by the remote side. + /** + * Return the audio port seen by the remote side. * @return unsigned int The external audio port */ - unsigned int getLocalExternAudioPort() { return _localExternalAudioPort; } + unsigned int getLocalExternAudioPort() { + return _localExternalAudioPort; + } - /** - * Return my IP [mutex protected] + /** + * Return my IP [mutex protected] * @return std::string The local IP */ const std::string& getLocalIp(); - /** - * Return port used locally (for my machine) [mutex protected] + /** + * Return port used locally (for my machine) [mutex protected] * @return unsigned int The local audio port */ unsigned int getLocalAudioPort(); - std::string getRecFileId(void){ return getPeerName(); } + std::string getRecFileId (void) { + return getPeerName(); + } - std::string getFileName(void) { return _filename; } + std::string getFileName (void) { + return _filename; + } - virtual bool setRecording(void); + virtual bool setRecording (void); protected: /** Protect every attribute that can be changed by two threads */ @@ -258,13 +294,13 @@ class Call: public Recordable{ unsigned int _localExternalAudioPort; - private: + private: /** Unique ID of the call */ CallID _id; - /** Unique conference ID, used exclusively in case of a conferece */ - CallID _confID; + /** Unique conference ID, used exclusively in case of a conferece */ + CallID _confID; /** Type of the call */ CallType _type; @@ -284,13 +320,13 @@ class Call: public Recordable{ /** Number of the peer */ std::string _peerNumber; - /** Display Name */ - std::string _displayName; + /** Display Name */ + std::string _displayName; - /** File name for his call : time YY-MM-DD */ + /** File name for his call : time YY-MM-DD */ std::string _filename; - + }; #endif diff --git a/sflphone-common/src/conference.cpp b/sflphone-common/src/conference.cpp index 3f15eec9257ebae5326c16f2496d1dd9423d7905..3e645628ddc70a52c88fac9f0337a1380e66f7b7 100644 --- a/sflphone-common/src/conference.cpp +++ b/sflphone-common/src/conference.cpp @@ -55,7 +55,7 @@ Conference::Conference() _nbParticipant = 0; _id = conf.append (s); - + Recordable::initRecFileName(); } @@ -183,6 +183,8 @@ bool Conference::setRecording() mbuffer->bindHalfDuplexOut (process_id); + Recordable::recorder.start(); + } // stop recording else { @@ -200,10 +202,9 @@ bool Conference::setRecording() mbuffer->unBindHalfDuplexOut (process_id); - } + // Recordable::recorder.start(); - - Recordable::recorder.start(); + } return recordStatus; diff --git a/sflphone-common/src/conference.h b/sflphone-common/src/conference.h index 77952531d1a7b979e6bcfb9c1d7e1a99c59d21b2..532c0abfcdb476b715819495b955d48c06729b0f 100644 --- a/sflphone-common/src/conference.h +++ b/sflphone-common/src/conference.h @@ -43,46 +43,53 @@ typedef std::string ConfID; typedef std::set<CallID> ParticipantSet; -class Conference: public Recordable{ +class Conference: public Recordable +{ public: enum ConferenceState {Active_Atached, Active_Detached, Hold}; - static int count; + static int count; Conference(); ~Conference(); - std::string getConfID() { return _id; } + std::string getConfID() { + return _id; + } - int getState(); + int getState(); - void setState(ConferenceState state); + void setState (ConferenceState state); - std::string getStateStr(); + std::string getStateStr(); - int getNbParticipants() { return _nbParticipant; } + int getNbParticipants() { + return _nbParticipant; + } - void add(CallID participant_id); + void add (CallID participant_id); - void remove(CallID participant_id); + void remove (CallID participant_id); - void bindParticipant(CallID participant_id); + void bindParticipant (CallID participant_id); - ParticipantSet getParticipantList(); + ParticipantSet getParticipantList(); - std::string getRecFileId(){ return getConfID(); } + std::string getRecFileId() { + return getConfID(); + } - virtual bool setRecording(); + virtual bool setRecording(); - private: + private: /** Unique ID of the conference */ CallID _id; - ConferenceState _confState; + ConferenceState _confState; ParticipantSet _participants; diff --git a/sflphone-common/src/config/Makefile.am b/sflphone-common/src/config/Makefile.am old mode 100644 new mode 100755 index d72225850fc3415ab1c5818cace8bc740401fe29..4d84e41e5949827722e41beb10127edf8d1bd7d8 --- a/sflphone-common/src/config/Makefile.am +++ b/sflphone-common/src/config/Makefile.am @@ -3,4 +3,21 @@ SUBDIRS = noinst_LTLIBRARIES = libconfig.la libconfig_la_SOURCES = \ - config.cpp config.h + config.cpp \ + yamlengine.cpp \ + yamlemitter.cpp \ + yamlparser.cpp \ + yamlnode.cpp + +noinst_HEADERS = \ + config.h \ + engine.h \ + serializable.h \ + yamlengine.h \ + yamlemitter.h \ + yamlparser.h \ + yamlnode.h + +libconfig_la_LDFLAGS = @yaml_LIBS@ + +libconfig_la_CFLAGS = @yaml_CFLAGS@ \ No newline at end of file diff --git a/sflphone-common/src/config/config.cpp b/sflphone-common/src/config/config.cpp index 22b85f99ca8332754cc87ac993864618952ec8f6..f48d396d00481a9fa872f5e292b440d849cd9384 100644 --- a/sflphone-common/src/config/config.cpp +++ b/sflphone-common/src/config/config.cpp @@ -38,6 +38,7 @@ #include <errno.h> #include <iostream> #include <string.h> +#include "yamlparser.h" namespace Conf { @@ -50,6 +51,7 @@ ConfigTree::ConfigTree() :_sections() // dtor ConfigTree::~ConfigTree() { + // erase every new ItemMap (by CreateSection) SectionMap::iterator iter = _sections.begin(); @@ -271,6 +273,8 @@ ConfigTree::setConfigTreeItem (const std::string& section, bool ConfigTree::saveConfigTree (const std::string& fileName) { + _debug ("ConfigTree: Save %s", fileName.c_str()); + if (fileName.empty() && _sections.begin() == _sections.end()) { return false; } @@ -319,6 +323,8 @@ ConfigTree::populateFromFile (const std::string& fileName) { bool out = false; + _debug ("ConfigTree: Populate from file %s", fileName.c_str()); + if (fileName.empty()) { return 0; } diff --git a/sflphone-common/src/config/engine.h b/sflphone-common/src/config/engine.h new file mode 100644 index 0000000000000000000000000000000000000000..c9c140a46e65e6efb37a5caa280d8b251f9f225e --- /dev/null +++ b/sflphone-common/src/config/engine.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#ifndef __ENGINE_H__ +#define __ENGINE_H__ + +#include <yaml.h> + +class Engine +{ + + public: + + virtual void open() = 0; + + virtual void close() = 0; + + virtual void write() = 0; + + virtual void read() = 0; + +}; + +#endif diff --git a/sflphone-common/src/config/serializable.h b/sflphone-common/src/config/serializable.h new file mode 100644 index 0000000000000000000000000000000000000000..bc37cb24c3a705f21afcc881168bb8926f036e9b --- /dev/null +++ b/sflphone-common/src/config/serializable.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#ifndef __SERIALIZABLE_H__ +#define __SERIALIZABLE_H__ + + +#include "yamlparser.h" +#include "yamlemitter.h" +#include "yamlnode.h" + +class Engine; +// class MappingNode; + +class Serializable +{ + + public: + + virtual void serialize (Conf::YamlEmitter *emitter) = 0; + + virtual void unserialize (Conf::MappingNode *map) = 0; + + private: + +}; + +#endif diff --git a/sflphone-common/src/config/yamlemitter.cpp b/sflphone-common/src/config/yamlemitter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3b6ba5c0c35d50e2e6d6b8a0071239f9d380a424 --- /dev/null +++ b/sflphone-common/src/config/yamlemitter.cpp @@ -0,0 +1,368 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#include "yamlemitter.h" +#include <stdio.h> +#include "../global.h" + +namespace Conf +{ + +YamlEmitter::YamlEmitter (const char *file) : filename (file), isFirstAccount (true) +{ + open(); +} + +YamlEmitter::~YamlEmitter() +{ + close(); +} + +void YamlEmitter::open() +{ + fd = fopen (filename.c_str(), "wb"); + + if (!fd) + throw YamlEmitterException ("Could not open file descriptor"); + + if (!yaml_emitter_initialize (&emitter)) + throw YamlEmitterException ("Could not initialize emitter"); + + // Use unicode format + yaml_emitter_set_unicode (&emitter, 1); + + yaml_emitter_set_output_file (&emitter, fd); + + yaml_document_initialize (&document, NULL, NULL, NULL, 0, 0); + + // Init the main configuration mapping + if ( (topLevelMapping = yaml_document_add_mapping (&document, NULL, YAML_BLOCK_MAPPING_STYLE)) == 0) + throw YamlEmitterException ("Could not create top level mapping"); +} + +void YamlEmitter::close() +{ + // yaml_emitter_delete(&emitter); + + if (!fd) + throw YamlEmitterException ("File descriptor not valid"); + + fclose (fd); + /* + if(!fclose(fd)) + throw YamlEmitterException("Error closing file descriptor"); + */ + + yaml_document_delete (&document); +} + +void YamlEmitter::read() {} + +void YamlEmitter::write() +{ + +} + +void YamlEmitter::serializeData() +{ + yaml_emitter_dump (&emitter, &document); +} + + +void YamlEmitter::serializeAccount (MappingNode *map) +{ + + std::string accountstr ("accounts"); + + int accountid, accountmapping; + + _debug ("YamlEmitter: Serialize account"); + + if (map->getType() != MAPPING) + throw YamlEmitterException ("Node type is not a mapping while writing account"); + + if (isFirstAccount) { + // accountSequence need to be static outside this scope since reused each time an account is written + if ( (accountid = yaml_document_add_scalar (&document, NULL, (yaml_char_t *) accountstr.c_str(), -1, YAML_PLAIN_SCALAR_STYLE)) == 0) + throw YamlEmitterException ("Could not add preference scalar to document"); + + if ( (accountSequence = yaml_document_add_sequence (&document, NULL, YAML_BLOCK_SEQUENCE_STYLE)) == 0) + throw YamlEmitterException ("Could not add sequence to document"); + + if (!yaml_document_append_mapping_pair (&document, topLevelMapping, accountid, accountSequence)) + throw YamlEmitterException ("Could not add mapping pair to top level mapping"); + + isFirstAccount = false; + } + + if ( (accountmapping = yaml_document_add_mapping (&document, NULL, YAML_BLOCK_MAPPING_STYLE)) == 0) + throw YamlEmitterException ("Could not add account mapping to document"); + + if (!yaml_document_append_sequence_item (&document, accountSequence, accountmapping)) + throw YamlEmitterException ("Could not append account mapping to sequence"); + + Mapping *internalmap = map->getMapping(); + Mapping::iterator iter = internalmap->begin(); + + while (iter != internalmap->end()) { + addMappingItem (accountmapping, iter->first, iter->second); + iter++; + } + +} + +void YamlEmitter::serializePreference (MappingNode *map) +{ + std::string preferencestr ("preferences"); + + int preferenceid, preferencemapping; + + _debug ("YamlEmitter: Serialize preference"); + + if (map->getType() != MAPPING) + throw YamlEmitterException ("Node type is not a mapping while writing preferences"); + + if ( (preferenceid = yaml_document_add_scalar (&document, NULL, (yaml_char_t *) preferencestr.c_str(), -1, YAML_PLAIN_SCALAR_STYLE)) == 0) + throw YamlEmitterException ("Could not add scalar to document"); + + if ( (preferencemapping = yaml_document_add_mapping (&document, NULL, YAML_BLOCK_MAPPING_STYLE)) == 0) + throw YamlEmitterException ("Could not add mapping to document"); + + if (!yaml_document_append_mapping_pair (&document, topLevelMapping, preferenceid, preferencemapping)) + throw YamlEmitterException ("Could not add mapping pair to top leve mapping"); + + Mapping *internalmap = map->getMapping(); + Mapping::iterator iter = internalmap->begin(); + + while (iter != internalmap->end()) { + addMappingItem (preferencemapping, iter->first, iter->second); + iter++; + } + +} + +void YamlEmitter::serializeVoipPreference (MappingNode *map) +{ + std::string preferencestr ("voipPreferences"); + + int preferenceid, preferencemapping; + + _debug ("YamlEmitter: Serialize voip preference"); + + if (map->getType() != MAPPING) + throw YamlEmitterException ("Node type is not a mapping while writing preferences"); + + if ( (preferenceid = yaml_document_add_scalar (&document, NULL, (yaml_char_t *) preferencestr.c_str(), -1, YAML_PLAIN_SCALAR_STYLE)) == 0) + throw YamlEmitterException ("Could not add scalar to document"); + + if ( (preferencemapping = yaml_document_add_mapping (&document, NULL, YAML_BLOCK_MAPPING_STYLE)) == 0) + throw YamlEmitterException ("Could not add mapping to document"); + + if (!yaml_document_append_mapping_pair (&document, topLevelMapping, preferenceid, preferencemapping)) + throw YamlEmitterException ("Could not add mapping pair to top leve mapping"); + + Mapping *internalmap = map->getMapping(); + Mapping::iterator iter = internalmap->begin(); + + while (iter != internalmap->end()) { + addMappingItem (preferencemapping, iter->first, iter->second); + iter++; + } + +} + +void YamlEmitter::serializeAddressbookPreference (MappingNode *map) +{ + std::string preferencestr ("addressbook"); + + int preferenceid, preferencemapping; + + _debug ("YamlEmitter: Serialize addressbook preferences"); + + if (map->getType() != MAPPING) + throw YamlEmitterException ("Node type is not a mapping while writing preferences"); + + if ( (preferenceid = yaml_document_add_scalar (&document, NULL, (yaml_char_t *) preferencestr.c_str(), -1, YAML_PLAIN_SCALAR_STYLE)) == 0) + throw YamlEmitterException ("Could not add scalar to document"); + + if ( (preferencemapping = yaml_document_add_mapping (&document, NULL, YAML_BLOCK_MAPPING_STYLE)) == 0) + throw YamlEmitterException ("Could not add mapping to document"); + + if (!yaml_document_append_mapping_pair (&document, topLevelMapping, preferenceid, preferencemapping)) + throw YamlEmitterException ("Could not add mapping pair to top leve mapping"); + + Mapping *internalmap = map->getMapping(); + Mapping::iterator iter = internalmap->begin(); + + while (iter != internalmap->end()) { + addMappingItem (preferencemapping, iter->first, iter->second); + iter++; + } + +} + +void YamlEmitter::serializeHooksPreference (MappingNode *map) +{ + std::string preferencestr ("hooks"); + + int preferenceid, preferencemapping; + + _debug ("YamlEmitter: Serialize hooks preferences"); + + if (map->getType() != MAPPING) + throw YamlEmitterException ("Node type is not a mapping while writing preferences"); + + if ( (preferenceid = yaml_document_add_scalar (&document, NULL, (yaml_char_t *) preferencestr.c_str(), -1, YAML_PLAIN_SCALAR_STYLE)) == 0) + throw YamlEmitterException ("Could not add scalar to document"); + + if ( (preferencemapping = yaml_document_add_mapping (&document, NULL, YAML_BLOCK_MAPPING_STYLE)) == 0) + throw YamlEmitterException ("Could not add mapping to document"); + + if (!yaml_document_append_mapping_pair (&document, topLevelMapping, preferenceid, preferencemapping)) + throw YamlEmitterException ("Could not add mapping pair to top leve mapping"); + + Mapping *internalmap = map->getMapping(); + Mapping::iterator iter = internalmap->begin(); + + while (iter != internalmap->end()) { + addMappingItem (preferencemapping, iter->first, iter->second); + iter++; + } + +} + + +void YamlEmitter::serializeAudioPreference (MappingNode *map) +{ + std::string preferencestr ("audio"); + + int preferenceid, preferencemapping; + + _debug ("YamlEmitter: Serialize hooks preferences"); + + if (map->getType() != MAPPING) + throw YamlEmitterException ("Node type is not a mapping while writing preferences"); + + if ( (preferenceid = yaml_document_add_scalar (&document, NULL, (yaml_char_t *) preferencestr.c_str(), -1, YAML_PLAIN_SCALAR_STYLE)) == 0) + throw YamlEmitterException ("Could not add scalar to document"); + + if ( (preferencemapping = yaml_document_add_mapping (&document, NULL, YAML_BLOCK_MAPPING_STYLE)) == 0) + throw YamlEmitterException ("Could not add mapping to document"); + + if (!yaml_document_append_mapping_pair (&document, topLevelMapping, preferenceid, preferencemapping)) + throw YamlEmitterException ("Could not add mapping pair to top leve mapping"); + + Mapping *internalmap = map->getMapping(); + Mapping::iterator iter = internalmap->begin(); + + while (iter != internalmap->end()) { + addMappingItem (preferencemapping, iter->first, iter->second); + iter++; + } + +} + + +void YamlEmitter::serializeShortcutPreference (MappingNode *map) +{ + std::string preferencestr ("shortcuts"); + + int preferenceid, preferencemapping; + + _debug ("YamlEmitter: Serialize shortcuts preferences"); + + if (map->getType() != MAPPING) + throw YamlEmitterException ("Node type is not a mapping while writing preferences"); + + if ( (preferenceid = yaml_document_add_scalar (&document, NULL, (yaml_char_t *) preferencestr.c_str(), -1, YAML_PLAIN_SCALAR_STYLE)) == 0) + throw YamlEmitterException ("Could not add scalar to document"); + + if ( (preferencemapping = yaml_document_add_mapping (&document, NULL, YAML_BLOCK_MAPPING_STYLE)) == 0) + throw YamlEmitterException ("Could not add mapping to document"); + + if (!yaml_document_append_mapping_pair (&document, topLevelMapping, preferenceid, preferencemapping)) + throw YamlEmitterException ("Could not add mapping pair to top leve mapping"); + + Mapping *internalmap = map->getMapping(); + Mapping::iterator iter = internalmap->begin(); + + while (iter != internalmap->end()) { + addMappingItem (preferencemapping, iter->first, iter->second); + iter++; + } + +} + + +void YamlEmitter::addMappingItem (int mappingid, Key key, YamlNode *node) +{ + + if (node->getType() == SCALAR) { + + int temp1, temp2; + + ScalarNode *sclr = (ScalarNode *) node; + + if ( (temp1 = yaml_document_add_scalar (&document, NULL, (yaml_char_t *) key.c_str(), -1, YAML_PLAIN_SCALAR_STYLE)) == 0) + throw YamlEmitterException ("Could not add scalar to document"); + + if ( (temp2 = yaml_document_add_scalar (&document, NULL, (yaml_char_t *) sclr->getValue().c_str(), -1, YAML_PLAIN_SCALAR_STYLE)) == 0) + throw YamlEmitterException ("Could not add scalar to document"); + + if (!yaml_document_append_mapping_pair (&document, mappingid, temp1, temp2)) + throw YamlEmitterException ("Could not append mapping pair to mapping"); + + } else if (node->getType() == MAPPING) { + + int temp1, temp2; + + if ( (temp1 = yaml_document_add_scalar (&document, NULL, (yaml_char_t *) key.c_str(), -1, YAML_PLAIN_SCALAR_STYLE)) == 0) + throw YamlEmitterException ("Could not add scalar to document"); + + if ( (temp2 = yaml_document_add_mapping (&document, NULL, YAML_BLOCK_MAPPING_STYLE)) == 0) + throw YamlEmitterException ("Could not add scalar to document"); + + if (!yaml_document_append_mapping_pair (&document, mappingid, temp1, temp2)) + throw YamlEmitterException ("Could not add mapping pair to mapping"); + + MappingNode *map = (MappingNode *) node; + Mapping *internalmap = map->getMapping(); + Mapping::iterator iter = internalmap->begin(); + + while (iter != internalmap->end()) { + addMappingItem (temp2, iter->first, iter->second); + iter++; + } + } else + throw YamlEmitterException ("Unknown node type while adding mapping node"); +} + + +} diff --git a/sflphone-common/src/config/yamlemitter.h b/sflphone-common/src/config/yamlemitter.h new file mode 100644 index 0000000000000000000000000000000000000000..e2e25a072444e1149303a0802069bced68f92ed7 --- /dev/null +++ b/sflphone-common/src/config/yamlemitter.h @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#ifndef __YAMLEMITTER_H__ +#define __YAMLEMITTER_H__ + +#include <yaml.h> +#include <exception> +#include <string> +#include "yamlnode.h" + +namespace Conf +{ + +#define EMITTER_BUFFERSIZE 65536 +#define EMITTER_MAXEVENT 1024 + +class YamlEmitterException : public std::exception +{ + public: + YamlEmitterException (const std::string& str="") throw() : errstr (str) {} + + virtual ~YamlEmitterException() throw() {} + + virtual const char *what() const throw() { + std::string expt ("YamlParserException occured: "); + expt.append (errstr); + + return expt.c_str(); + } + private: + std::string errstr; + +}; + +class YamlEmitter +{ + + public: + + YamlEmitter (const char *file); + + ~YamlEmitter(); + + void open(); + + void close(); + + void read(); + + void write(); + + void serializeAccount (MappingNode *map); + + void serializePreference (MappingNode *map); + + void serializeVoipPreference (MappingNode *map); + + void serializeAddressbookPreference (MappingNode *map); + + void serializeHooksPreference (MappingNode *map); + + void serializeAudioPreference (MappingNode *map); + + void serializeShortcutPreference (MappingNode *map); + + void writeAudio(); + + void writeHooks(); + + void writeVoiplink(); + + void serializeData(); + + private: + + void addMappingItem (int mappingid, Key key, YamlNode *node); + + std::string filename; + + FILE *fd; + + /** + * The parser structure. + */ + yaml_emitter_t emitter; + + /** + * The event structure array. + */ + yaml_event_t events[EMITTER_MAXEVENT]; + + /** + * + */ + unsigned char buffer[EMITTER_BUFFERSIZE]; + + + /** + * Main document for this serialization + */ + yaml_document_t document; + + /** + * Reference id to the top levell mapping when creating + */ + int topLevelMapping; + + /** + * We need to add the account sequence if this is the first account to be + */ + bool isFirstAccount; + + /** + * Reference to the account sequence + */ + int accountSequence; + + friend class ConfigurationTest; + +}; + +} + +#endif diff --git a/sflphone-common/src/config/yamlengine.cpp b/sflphone-common/src/config/yamlengine.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9e2aa30dafb21e370c9179012f994eb555875a07 --- /dev/null +++ b/sflphone-common/src/config/yamlengine.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#include "yamlengine.h" +#include "../global.h" + + +namespace Conf +{ + +YamlEngine::YamlEngine() {} + +YamlEngine::~YamlEngine() {} + +void YamlEngine::openConfigFile() +{ + + Conf::YamlParser *parser = NULL; + + try { + parser = new Conf::YamlParser ("sequence.yml"); + } catch (Conf::YamlParserException &e) { + _error ("ConfigTree: %s", e.what()); + } + + try { + parser->serializeEvents(); + } catch (Conf::YamlParserException &e) { + _error ("ConfigTree: %s", e.what()); + } + + try { + document = parser->composeEvents(); + } catch (Conf::YamlParserException &e) { + _error ("ConfigTree: %s", e.what()); + } + + try { + delete parser; + parser = NULL; + } catch (Conf::YamlParserException &e) { + _error ("ConfigTree: %s", e.what()); + } +} + +void YamlEngine::closeConfigFile() +{ + +} + +void YamlEngine::read() {} + +void YamlEngine::write() {} + +} diff --git a/sflphone-common/src/config/yamlengine.h b/sflphone-common/src/config/yamlengine.h new file mode 100644 index 0000000000000000000000000000000000000000..fcf9cd849b37e11bfe6334c7a61fd6d86728efbc --- /dev/null +++ b/sflphone-common/src/config/yamlengine.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#ifndef __YAMLENGINE_H__ +#define __YAMLENGINE_H__ + +#include "engine.h" +#include "yamlnode.h" +#include "yamlparser.h" +#include "yamlemitter.h" +#include <exception> + +namespace Conf +{ + +class YamlEngineException : public std::exception +{ + + virtual const char *what() const throw() { + return "YamlEngineException occured"; + } +}; + +class YamlEngine : public Engine +{ + + public: + + YamlEngine(); + + ~YamlEngine(); + + virtual void openConfigFile(); + + virtual void closeConfigFile(); + + virtual void write(); + + virtual void read(); + + private: + + YamlParser *parser; + + YamlEmitter *emitter; + + YamlDocument *document; + +}; + +} + +#endif diff --git a/sflphone-common/src/config/yamlnode.cpp b/sflphone-common/src/config/yamlnode.cpp new file mode 100644 index 0000000000000000000000000000000000000000..00a3aa1d8db8a99ea4baf13e922ec37c4c7e4732 --- /dev/null +++ b/sflphone-common/src/config/yamlnode.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#include "yamlnode.h" +#include "src/global.h" + +namespace Conf +{ + + +void YamlDocument::addNode (YamlNode *node) +{ + Sequence::iterator it = doc.end(); + doc.insert (it, node); +} + +YamlNode *YamlDocument::popNode() +{ + Sequence::iterator it = doc.begin(); + YamlNode *node = doc.front(); + + //removed element's destructor is called + doc.pop_front(); + + return node; +} + +void MappingNode::addNode (YamlNode *node) +{ + Mapping::iterator it = map.end(); + map.insert (it, std::pair<Key, YamlNode *> (tmpKey, node)); +} + +void MappingNode::setKeyValue (Key key, YamlNode *value) +{ + Mapping::iterator it = map.end(); + map.insert (it, std::pair<Key, YamlNode *> (key, value)); +} + +void MappingNode::removeKeyValue (Key key) +{ + + Mapping::iterator it = map.find (key); + map.erase (it); +} + + +YamlNode *MappingNode::getValue (Key key) +{ + Mapping::iterator it = map.find (key); + + if (it != map.end()) { + return it->second; + } else { + _debug ("MappingNode: Could not find %s", key.c_str()); + return NULL; + } +} + + +void SequenceNode::addNode (YamlNode *node) +{ + Sequence::iterator it = seq.end(); + seq.insert (it, node); +} + +} + diff --git a/sflphone-common/src/config/yamlnode.h b/sflphone-common/src/config/yamlnode.h new file mode 100644 index 0000000000000000000000000000000000000000..ec2de80237669560dcafa065f658d2aa91b82400 --- /dev/null +++ b/sflphone-common/src/config/yamlnode.h @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#ifndef __YAMLNODE_H__ +#define __YAMLNODE_H__ + +#include <string> +#include <list> +#include <map> +#include <exception> + +namespace Conf +{ + + +class YamlNode; + +typedef std::string Key; +typedef std::string Value; +typedef std::list<YamlNode *> Sequence; +typedef std::map<Key, YamlNode *> Mapping; + +class YamlNodeException : public std::exception +{ + + public: + YamlNodeException (const std::string& str="") throw() : errstr (str) {} + + virtual ~YamlNodeException() throw() {} + + virtual const char *what() const throw() { + std::string expt ("YamlNodeException occured: "); + expt.append (errstr); + + return expt.c_str(); + } + private: + std::string errstr; + +}; + +enum NodeType { DOCUMENT, SCALAR, MAPPING, SEQUENCE }; + +class YamlNode +{ + + public: + + YamlNode (NodeType t, YamlNode *top=NULL) : type (t), topNode (top) {} + + ~YamlNode() {} + + NodeType getType() { + return type; + } + + YamlNode *getTopNode() { + return topNode; + } + + private: + + NodeType type; + + YamlNode *topNode; + +}; + + +class YamlDocument : YamlNode +{ + + public: + + YamlDocument (YamlNode* top=NULL) : YamlNode (DOCUMENT, top) {} + + ~YamlDocument() {} + + void addNode (YamlNode *node); + + YamlNode *popNode (void); + + Sequence *getSequence (void) { + return &doc; + } + + private: + + Sequence doc; + +}; + +class SequenceNode : public YamlNode +{ + + public: + + SequenceNode (YamlNode *top) : YamlNode (SEQUENCE, top) {} + + ~SequenceNode() {} + + Sequence *getSequence() { + return &seq; + } + + void addNode (YamlNode *node); + + private: + + Sequence seq; + +}; + + +class MappingNode : public YamlNode +{ + + public: + + MappingNode (YamlNode *top) : YamlNode (MAPPING, top) {} + + ~MappingNode() {} + + Mapping *getMapping() { + return ↦ + } + + void addNode (YamlNode *node); + + void setTmpKey (Key key) { + tmpKey = key; + } + + void setKeyValue (Key key, YamlNode *value); + + void removeKeyValue (Key key); + + YamlNode *getValue (Key key); + + private: + + Mapping map; + + Key tmpKey; + +}; + + +class ScalarNode : public YamlNode +{ + + public: + + ScalarNode (Value v="", YamlNode *top=NULL) : YamlNode (SCALAR, top), val (v) {} + + ~ScalarNode() {} + + Value getValue() { + return val; + } + + void setValue (Value v) { + val = v; + } + + private: + + Value val; + +}; + + +} + + + +#endif diff --git a/sflphone-common/src/config/yamlparser.cpp b/sflphone-common/src/config/yamlparser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b4d8c5de47ac3afd76f36f778bbffa970b7ff614 --- /dev/null +++ b/sflphone-common/src/config/yamlparser.cpp @@ -0,0 +1,483 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#include "yamlparser.h" + +#include "../global.h" +#include "config.h" +#include "yamlnode.h" +#include <stdio.h> + +namespace Conf +{ + +YamlParser::YamlParser (const char *file) : filename (file) + , accountSequence (NULL) + , preferenceSequence (NULL) + , addressbookSequence (NULL) + , audioSequence (NULL) + , hooksSequence (NULL) + , voiplinkSequence (NULL) + , shortcutSequence (NULL) +{ + memset (buffer, 0, PARSER_BUFFERSIZE); + + open(); +} + +YamlParser::~YamlParser() +{ + close(); +} + +void YamlParser::open() +{ + + fd = fopen (filename.c_str(), "rb"); + + if (!fd) + throw YamlParserException ("Could not open file descriptor"); + + if (!yaml_parser_initialize (&parser)) + throw YamlParserException ("Could not open file descriptor"); + + yaml_parser_set_input_file (&parser, fd); +} + +void YamlParser::close() +{ + + yaml_parser_delete (&parser); + + if (!fd) + throw YamlParserException ("File descriptor not valid"); + + fclose (fd); + // if(!fclose(fd)) + // throw YamlParserException("Error closing file descriptor"); + + +} + +void YamlParser::serializeEvents() +{ + bool done = false; + yaml_event_t event; + + while (!done) { + + if (!yaml_parser_parse (&parser, &event)) + throw YamlParserException ("Error while parsing"); + + done = (event.type == YAML_STREAM_END_EVENT); + + if (eventNumber > PARSER_MAXEVENT) + throw YamlParserException ("Reached maximum of event"); + + if (!copyEvent (& (events[eventNumber++]), &event)) + throw YamlParserException ("Error copying event"); + + } +} + + +int YamlParser::copyEvent (yaml_event_t *event_to, yaml_event_t *event_from) +{ + + switch (event_from->type) { + case YAML_STREAM_START_EVENT: { + // _debug("YAML_STREAM_START_EVENT"); + return yaml_stream_start_event_initialize (event_to, + event_from->data.stream_start.encoding); + } + + case YAML_STREAM_END_EVENT: { + //_debug("YAML_STREAM_END_EVENT"); + return yaml_stream_end_event_initialize (event_to); + } + + case YAML_DOCUMENT_START_EVENT: { + // _debug("YAML_DOCUMENT_START_EVENT"); + return yaml_document_start_event_initialize (event_to, + event_from->data.document_start.version_directive, + event_from->data.document_start.tag_directives.start, + event_from->data.document_start.tag_directives.end, + event_from->data.document_start.implicit); + } + + case YAML_DOCUMENT_END_EVENT: { + // _debug("YAML_DOCUMENT_END_EVENT"); + return yaml_document_end_event_initialize (event_to, + event_from->data.document_end.implicit); + } + case YAML_ALIAS_EVENT: { + // _debug("YAML_ALIAS_EVENT"); + return yaml_alias_event_initialize (event_to, + event_from->data.alias.anchor); + } + case YAML_SCALAR_EVENT: { + // _debug("YAML_SCALAR_EVENT"); + return yaml_scalar_event_initialize (event_to, + event_from->data.scalar.anchor, + event_from->data.scalar.tag, + event_from->data.scalar.value, + event_from->data.scalar.length, + event_from->data.scalar.plain_implicit, + event_from->data.scalar.quoted_implicit, + event_from->data.scalar.style); + } + case YAML_SEQUENCE_START_EVENT: { + // _debug("YAML_SEQUENCE_START_EVENT"); + return yaml_sequence_start_event_initialize (event_to, + event_from->data.sequence_start.anchor, + event_from->data.sequence_start.tag, + event_from->data.sequence_start.implicit, + event_from->data.sequence_start.style); + } + case YAML_SEQUENCE_END_EVENT: { + // _debug("YAML_SEQUENCE_END_EVENT"); + return yaml_sequence_end_event_initialize (event_to); + } + case YAML_MAPPING_START_EVENT: { + // _debug("YAML_MAPPING_START_EVENT"); + return yaml_mapping_start_event_initialize (event_to, + event_from->data.mapping_start.anchor, + event_from->data.mapping_start.tag, + event_from->data.mapping_start.implicit, + event_from->data.mapping_start.style); + } + case YAML_MAPPING_END_EVENT: { + // _debug("YAML_MAPPING_END_EVENT"); + return yaml_mapping_end_event_initialize (event_to); + + } + default: + assert (1); + + } + + return 0; +} + + +YamlDocument *YamlParser::composeEvents() +{ + + // _debug("YamlParser: Compose Events"); + + if (eventNumber == 0) + throw YamlParserException ("No event available"); + + if (events[0].type != YAML_STREAM_START_EVENT) + throw YamlParserException ("Parsing does not start with stream start"); + + eventIndex = 0; + + processStream(); + + return doc; +} + +void YamlParser::processStream () +{ + + // _debug("YamlParser: process stream"); + + while ( (eventIndex < eventNumber) && (events[eventIndex].type != YAML_STREAM_END_EVENT)) { + + if (events[eventIndex].type == YAML_DOCUMENT_START_EVENT) + processDocument(); + + eventIndex++; + } + + if (events[eventIndex].type != YAML_STREAM_END_EVENT) + throw YamlParserException ("Did not found end of stream"); +} + + +void YamlParser::processDocument() +{ + // _debug("YamlParser: process document"); + + doc = new YamlDocument(); + + if (!doc) + throw YamlParserException ("Not able to create new document"); + + while ( (eventIndex < eventNumber) && (events[eventIndex].type != YAML_DOCUMENT_END_EVENT)) { + + switch (events[eventIndex].type) { + case YAML_SCALAR_EVENT: + processScalar ( (YamlNode *) doc); + break; + case YAML_SEQUENCE_START_EVENT: + processSequence ( (YamlNode *) doc); + break; + case YAML_MAPPING_START_EVENT: + processMapping ( (YamlNode *) doc); + break; + default: + break; + } + + eventIndex++; + } + + if (events[eventIndex].type != YAML_DOCUMENT_END_EVENT) + throw YamlParserException ("Did not found end of document"); + +} + + +void YamlParser::processScalar (YamlNode *topNode) +{ + + // _debug("YamlParser: process scalar"); + + if (!topNode) + throw YamlParserException ("No container for scalar"); + + char buffer[1000]; + snprintf (buffer, 1000, "%s", events[eventIndex].data.scalar.value); + // _debug("and the scalar is: %s", buffer); + + ScalarNode *sclr = new ScalarNode (buffer, topNode); + + switch (topNode->getType()) { + case DOCUMENT: + ( (YamlDocument *) (topNode))->addNode (sclr); + break; + case SEQUENCE: + ( (SequenceNode *) (topNode))->addNode (sclr); + break; + case MAPPING: + ( (MappingNode *) (topNode))->addNode (sclr); + case SCALAR: + default: + break; + } +} + + +void YamlParser::processSequence (YamlNode *topNode) +{ + _debug ("YamlParser: process sequence"); + + if (!topNode) + throw YamlParserException ("No container for sequence"); + + SequenceNode *seq = new SequenceNode (topNode); + + switch (topNode->getType()) { + case DOCUMENT: + ( (YamlDocument *) (topNode))->addNode (seq); + break; + case SEQUENCE: + ( (SequenceNode *) (topNode))->addNode (seq); + break; + case MAPPING: + ( (MappingNode *) (topNode))->addNode (seq); + case SCALAR: + default: + break; + } + + eventIndex++; + + while ( (eventIndex < eventNumber) && (events[eventIndex].type != YAML_SEQUENCE_END_EVENT)) { + + switch (events[eventIndex].type) { + case YAML_SCALAR_EVENT: + processScalar (seq); + break; + case YAML_SEQUENCE_START_EVENT: + processSequence (seq); + break; + case YAML_MAPPING_START_EVENT: + processMapping (seq); + break; + default: + break; + } + + eventIndex++; + } + + if (events[eventIndex].type != YAML_SEQUENCE_END_EVENT) + throw YamlParserException ("Did not found end of sequence"); +} + + +void YamlParser::processMapping (YamlNode *topNode) +{ + // _debug("YamlParser: process mapping"); + + if (!topNode) + throw YamlParserException ("No container for mapping"); + + MappingNode *map = new MappingNode (topNode); + + switch (topNode->getType()) { + case DOCUMENT: + ( (YamlDocument *) (topNode))->addNode (map); + break; + case SEQUENCE: + ( (SequenceNode *) (topNode))->addNode (map); + break; + case MAPPING: + ( (MappingNode *) (topNode))->addNode (map); + case SCALAR: + default: + break; + } + + eventIndex++; + + while ( (eventIndex < eventNumber) && (events[eventIndex].type != YAML_MAPPING_END_EVENT)) { + + if (events[eventIndex].type != YAML_SCALAR_EVENT) + throw YamlParserException ("Mapping not followed by a key"); + + char buffer[1000]; + snprintf (buffer, 1000, "%s", events[eventIndex].data.scalar.value); + map->setTmpKey (Key (buffer)); + // _debug("KEY %s", buffer); + + eventIndex++; + + switch (events[eventIndex].type) { + case YAML_SCALAR_EVENT: + processScalar (map); + break; + case YAML_SEQUENCE_START_EVENT: + processSequence (map); + break; + case YAML_MAPPING_START_EVENT: + processMapping (map); + break; + default: + break; + } + + eventIndex++; + } + + if (events[eventIndex].type != YAML_MAPPING_END_EVENT) + throw YamlParserException ("Did not found end of mapping"); +} + +void YamlParser::constructNativeData() +{ + + Sequence *seq; + + seq = doc->getSequence(); + + Sequence::iterator iter = seq->begin(); + + while (iter != seq->end()) { + + switch ( (*iter)->getType()) { + case SCALAR: + // _debug("construct scalar"); + throw YamlParserException ("No scalar allowed at document level, expect a mapping"); + break; + case SEQUENCE: + // _debug("construct sequence"); + throw YamlParserException ("No sequence allowed at document level, expect a mapping"); + break; + case MAPPING: { + // _debug("construct mapping"); + MappingNode *map = (MappingNode *) (*iter); + mainNativeDataMapping (map); + break; + } + default: + throw YamlParserException ("Unknown type in configuration file, expect a mapping"); + break; + } + + iter++; + + } + +} + + +void YamlParser::mainNativeDataMapping (MappingNode *map) +{ + + + Mapping::iterator iter = map->getMapping()->begin(); + + Key accounts ("accounts"); + Key addressbook ("addressbook"); + Key audio ("audio"); + Key hooks ("hooks"); + Key preferences ("preferences"); + Key voiplink ("voipPreferences"); + Key shortcuts ("shortcuts"); + + while (iter != map->getMapping()->end()) { + + _debug ("Iterating: %s", iter->first.c_str()); + + if (accounts.compare (iter->first) == 0) { + _debug ("YamlParser: Adding voip account preferences"); + accountSequence = (SequenceNode *) (iter->second); + } else if (addressbook.compare (iter->first) == 0) { + _debug ("YamlParser: Adding addressbook preference"); + addressbookSequence = (SequenceNode *) (iter->second); + } else if (audio.compare (iter->first) == 0) { + _debug ("YamlParser: Adding audio preference"); + audioSequence = (SequenceNode *) (iter->second); + } else if (hooks.compare (iter->first) == 0) { + _debug ("YamlParser: Adding hooks preference"); + hooksSequence = (SequenceNode *) (iter->second); + } else if (preferences.compare (iter->first) == 0) { + _debug ("YamlParser: Adding preference preference"); + preferenceSequence = (SequenceNode *) (iter->second); + } else if (voiplink.compare (iter->first) == 0) { + _debug ("YamlParser: Adding voip preference"); + voiplinkSequence = (SequenceNode *) (iter->second); + } else if (shortcuts.compare (iter->first) == 0) { + _debug ("YamlParser: Adding shortcut preference"); + shortcutSequence = (SequenceNode *) (iter->second); + } else + throw YamlParserException ("Unknow map key in configuration"); + + iter++; + } + + // _debug("Done"); +} + +} diff --git a/sflphone-common/src/config/yamlparser.h b/sflphone-common/src/config/yamlparser.h new file mode 100644 index 0000000000000000000000000000000000000000..58c92826b926e903a8ffa5fd2ce9811fba229b73 --- /dev/null +++ b/sflphone-common/src/config/yamlparser.h @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#ifndef __YAMLPARSER_H__ +#define __YAMLPARSER_H__ + +#include "yamlnode.h" +#include <yaml.h> +#include <stdio.h> +#include <exception> +#include <string> + +namespace Conf +{ + +#define PARSER_BUFFERSIZE 65536 +#define PARSER_MAXEVENT 1024 + +class YamlParserException : public std::exception +{ + public: + YamlParserException (const std::string& str="") throw() : errstr (str) {} + + virtual ~YamlParserException() throw() {} + + virtual const char *what() const throw() { + std::string expt ("YamlParserException occured: "); + expt.append (errstr); + + return expt.c_str(); + } + private: + std::string errstr; +}; + + +class YamlParser +{ + + public: + + YamlParser (const char *file); + + ~YamlParser(); + + void open(); + + void close(); + + void serializeEvents(); + + YamlDocument *composeEvents(); + + void constructNativeData(); + + SequenceNode *getAccountSequence (void) { + return accountSequence; + }; + + SequenceNode *getPreferenceSequence (void) { + return preferenceSequence; + } + + SequenceNode *getAddressbookSequence (void) { + return addressbookSequence; + } + + SequenceNode *getAudioSequence (void) { + return audioSequence; + } + + SequenceNode *getHookSequence (void) { + return hooksSequence; + } + + SequenceNode *getVoipPreferenceSequence (void) { + return voiplinkSequence; + } + + SequenceNode *getShortcutSequence (void) { + return shortcutSequence; + } + + private: + + /** + * Copy yaml parser event in event_to according to their type. + */ + int copyEvent (yaml_event_t *event_to, yaml_event_t *event_from); + + void processStream (void); + + void processDocument (void); + + void processScalar (YamlNode *topNode); + + void processSequence (YamlNode *topNode); + + void processMapping (YamlNode *topNode); + + void mainNativeDataMapping (MappingNode *map); + + // void buildAccounts(SequenceNode *map); + + std::string filename; + + FILE *fd; + + /** + * The parser structure. + */ + yaml_parser_t parser; + + /** + * The event structure array. + */ + yaml_event_t events[PARSER_MAXEVENT]; + + /** + * + */ + unsigned char buffer[PARSER_BUFFERSIZE]; + + /** + * Number of event actually parsed + */ + int eventNumber; + + YamlDocument *doc; + + int eventIndex; + + SequenceNode *accountSequence; + + SequenceNode *preferenceSequence; + + SequenceNode *addressbookSequence; + + SequenceNode *audioSequence; + + SequenceNode *hooksSequence; + + SequenceNode *voiplinkSequence; + + SequenceNode *shortcutSequence; + +}; + +} + +#endif diff --git a/sflphone-common/src/dbus/callmanager.cpp b/sflphone-common/src/dbus/callmanager.cpp index e52e544ed8036b3d4c2f9026e54027f1b17866cb..7e2af36cfb64cafaabf44ac3e20d225c4939f3ad 100644 --- a/sflphone-common/src/dbus/callmanager.cpp +++ b/sflphone-common/src/dbus/callmanager.cpp @@ -333,18 +333,23 @@ sfl::AudioZrtpSession * CallManager::getAudioZrtpSession (const std::string& cal SIPVoIPLink * link = NULL; link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (AccountNULL)); - if (link == NULL) { - _debug ("Failed to get sip link"); + if (!link) { + _debug ("CallManager: Failed to get sip link"); throw CallManagerException(); } SIPCall *call = link->getSIPCall (callID); + if (!call) { + _debug ("CallManager: Call id %d is not valid", callID.c_str()); + throw CallManagerException(); + } + sfl::AudioRtpFactory * audioRtp = NULL; audioRtp = call->getAudioRtp(); - if (audioRtp == NULL) { - _debug ("Failed to get AudioRtpFactory"); + if (!audioRtp) { + _debug ("CallManager: Failed to get AudioRtpFactory"); throw CallManagerException(); } @@ -352,8 +357,8 @@ sfl::AudioZrtpSession * CallManager::getAudioZrtpSession (const std::string& cal zSession = audioRtp->getAudioZrtpSession(); - if (zSession == NULL) { - _debug ("Failed to get AudioZrtpSession"); + if (!zSession) { + _debug ("CallManager: Failed to get AudioZrtpSession"); throw CallManagerException(); } @@ -369,7 +374,8 @@ CallManager::setSASVerified (const std::string& callID) zSession = getAudioZrtpSession (callID); zSession->SASVerified(); } catch (...) { - throw; + return; + // throw; } } @@ -383,7 +389,8 @@ CallManager::resetSASVerified (const std::string& callID) zSession = getAudioZrtpSession (callID); zSession->resetSASVerified(); } catch (...) { - throw; + return; + // throw; } } @@ -398,7 +405,8 @@ CallManager::setConfirmGoClear (const std::string& callID) zSession = getAudioZrtpSession (callID); zSession->goClearOk(); } catch (...) { - throw; + return; + // throw; } } @@ -413,7 +421,8 @@ CallManager::requestGoClear (const std::string& callID) zSession = getAudioZrtpSession (callID); zSession->requestGoClear(); } catch (...) { - throw; + return; + /// throw; } } @@ -429,7 +438,8 @@ CallManager::acceptEnrollment (const std::string& callID, const bool& accepted) zSession = getAudioZrtpSession (callID); zSession->acceptEnrollment (accepted); } catch (...) { - throw; + return; + // throw; } } @@ -445,7 +455,8 @@ CallManager::setPBXEnrollment (const std::string& callID, const bool& yesNo) zSession = getAudioZrtpSession (callID); zSession->setPBXEnrollment (yesNo); } catch (...) { - throw; + return; + // throw; } } diff --git a/sflphone-common/src/dbus/callmanager.h b/sflphone-common/src/dbus/callmanager.h index 8646dcbf668a793e75f1eff9c68e4c0837c5b27b..8a232f5ec62b423eb631920b7e8f3411a5c4941c 100644 --- a/sflphone-common/src/dbus/callmanager.h +++ b/sflphone-common/src/dbus/callmanager.h @@ -1,17 +1,17 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com> - * + * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -31,87 +31,91 @@ #ifndef __SFL_CALLMANAGER_H__ #define __SFL_CALLMANAGER_H__ +#pragma GCC diagnostic ignored "-Wignored-qualifiers" +#pragma GCC diagnostic ignored "-Wunused-parameter" #include "callmanager-glue.h" +#pragma GCC diagnostic warning "-Wignored-qualifiers" +#pragma GCC diagnostic warning "-Wunused-parameter" #include <dbus-c++/dbus.h> #include <exception> class CallManagerException: public std::exception { - virtual const char* what() const throw() - { - return "A CallManagerException occured"; - } + virtual const char* what() const throw() { + return "A CallManagerException occured"; + } }; -namespace sfl { - class AudioZrtpSession; +namespace sfl +{ +class AudioZrtpSession; } class CallManager -: public org::sflphone::SFLphone::CallManager_adaptor, - public DBus::IntrospectableAdaptor, - public DBus::ObjectAdaptor + : public org::sflphone::SFLphone::CallManager_adaptor, + public DBus::IntrospectableAdaptor, + public DBus::ObjectAdaptor { - public: - - CallManager(DBus::Connection& connection); - static const char* SERVER_PATH; - - /* methods exported by this interface, - * you will have to implement them in your ObjectAdaptor - */ - - /* Call related methods */ - void placeCall( const std::string& accountID, const std::string& callID, const std::string& to ); - void placeCallFirstAccount( const std::string& callID, const std::string& to ); - - void refuse( const std::string& callID ); - void accept( const std::string& callID ); - void hangUp( const std::string& callID ); - void hold( const std::string& callID ); - void unhold( const std::string& callID ); - void transfert( const std::string& callID, const std::string& to ); - std::map< std::string, std::string > getCallDetails( const std::string& callID ); - std::vector< std::string > getCallList (void); - std::string getCurrentCallID( ); - - /* Conference related methods */ - void joinParticipant( const std::string& sel_callID, const std::string& drag_callID ); - void addParticipant( const std::string& callID, const std::string& confID ); - void addMainParticipant( const std::string& confID ); - void detachParticipant( const std::string& callID ); - void joinConference( const std::string& sel_confID, const std::string& drag_confID ); - void hangUpConference( const std::string& confID ); - void holdConference( const std::string& confID ); - void unholdConference( const std::string& confID ); - std::vector< std::string > getConferenceList (void); - std::vector< std::string > getParticipantList (const std::string& confID); - std::map< std::string, std::string > getConferenceDetails ( const std::string& callID ); - - /* General audio methods */ - void setVolume( const std::string& device, const double& value ); - double getVolume( const std::string& device ); - void setRecording( const std::string& callID ); - bool getIsRecording(const std::string& callID); - std::string getCurrentCodecName(const std::string& callID); - void playDTMF( const std::string& key ); - void startTone( const int32_t& start, const int32_t& type ); - - /* Security related methods */ - void setSASVerified(const std::string& callID); - void resetSASVerified(const std::string& callID); - void setConfirmGoClear(const std::string& callID); - void requestGoClear(const std::string& callID); - void acceptEnrollment(const std::string& callID, const bool& accepted); - void setPBXEnrollment(const std::string& callID, const bool& yesNo); - - /* Instant messaging */ - void sendTextMessage (const std::string& callID, const std::string& message); - - private: - - sfl::AudioZrtpSession * getAudioZrtpSession(const std::string& callID); + public: + + CallManager (DBus::Connection& connection); + static const char* SERVER_PATH; + + /* methods exported by this interface, + * you will have to implement them in your ObjectAdaptor + */ + + /* Call related methods */ + void placeCall (const std::string& accountID, const std::string& callID, const std::string& to); + void placeCallFirstAccount (const std::string& callID, const std::string& to); + + void refuse (const std::string& callID); + void accept (const std::string& callID); + void hangUp (const std::string& callID); + void hold (const std::string& callID); + void unhold (const std::string& callID); + void transfert (const std::string& callID, const std::string& to); + std::map< std::string, std::string > getCallDetails (const std::string& callID); + std::vector< std::string > getCallList (void); + std::string getCurrentCallID(); + + /* Conference related methods */ + void joinParticipant (const std::string& sel_callID, const std::string& drag_callID); + void addParticipant (const std::string& callID, const std::string& confID); + void addMainParticipant (const std::string& confID); + void detachParticipant (const std::string& callID); + void joinConference (const std::string& sel_confID, const std::string& drag_confID); + void hangUpConference (const std::string& confID); + void holdConference (const std::string& confID); + void unholdConference (const std::string& confID); + std::vector< std::string > getConferenceList (void); + std::vector< std::string > getParticipantList (const std::string& confID); + std::map< std::string, std::string > getConferenceDetails (const std::string& callID); + + /* General audio methods */ + void setVolume (const std::string& device, const double& value); + double getVolume (const std::string& device); + void setRecording (const std::string& callID); + bool getIsRecording (const std::string& callID); + std::string getCurrentCodecName (const std::string& callID); + void playDTMF (const std::string& key); + void startTone (const int32_t& start, const int32_t& type); + + /* Security related methods */ + void setSASVerified (const std::string& callID); + void resetSASVerified (const std::string& callID); + void setConfirmGoClear (const std::string& callID); + void requestGoClear (const std::string& callID); + void acceptEnrollment (const std::string& callID, const bool& accepted); + void setPBXEnrollment (const std::string& callID, const bool& yesNo); + + /* Instant messaging */ + void sendTextMessage (const std::string& callID, const std::string& message); + + private: + + sfl::AudioZrtpSession * getAudioZrtpSession (const std::string& callID); }; diff --git a/sflphone-common/src/dbus/configurationmanager-introspec.xml b/sflphone-common/src/dbus/configurationmanager-introspec.xml old mode 100644 new mode 100755 index f75d22c662e8b34451ef22540ec124e3c7f25b08..c2818831f9e18520fe3bbfbe9c0982bd6a2133a2 --- a/sflphone-common/src/dbus/configurationmanager-introspec.xml +++ b/sflphone-common/src/dbus/configurationmanager-introspec.xml @@ -101,29 +101,15 @@ </arg> </method> - <method name="setNumberOfCredential" tp:name-for-bindings="setNumberOfCredential"> + <method name="deleteAllCredential" tp:name-for-bindings="deleteAllCredential"> <tp:docstring> </tp:docstring> <arg type="s" name="accountID" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - <arg type="i" name="number" direction="in"> <tp:docstring> </tp:docstring> </arg> </method> - <method name="deleteAllCredential" tp:name-for-bindings="deleteAllCredential"> - <tp:docstring> - </tp:docstring> - <arg type="s" name="accountID" direction="in"> - <tp:docstring> - Account ID - </tp:docstring> - </arg> - </method> - <method name="getIp2IpDetails" tp:name-for-bindings="getIp2IpDetails"> <tp:docstring> Get configuration settings of the IP2IP_PROFILE. They are sligthly different from account settings since no VoIP accounts are involved. @@ -207,55 +193,55 @@ <method name="addAccount" tp:name-for-bindings="addAccount"> <tp:docstring> - Add a new account. When created, the signal <tp:member-ref>accountsChanged</tp:member-ref> is emitted. The clients must then call <tp:member-ref>getAccountList</tp:member-ref> to update their internal data structure. - <tp:rationale>If no details are specified, the default parameters are used.</tp:rationale> - <tp:rationale>The core tries to register the account as soon it is created.</tp:rationale> + Add a new account. When created, the signal <tp:member-ref>accountsChanged</tp:member-ref> is emitted. The clients must then call <tp:member-ref>getAccountList</tp:member-ref> to update their internal data structure. + <tp:rationale>If no details are specified, the default parameters are used.</tp:rationale> + <tp:rationale>The core tries to register the account as soon it is created.</tp:rationale> </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="MapStringString"/> <arg type="a{ss}" name="details" direction="in" tp:type="String_String_Map"> - <tp:docstring> - The new account settings - </tp:docstring> + <tp:docstring> + The new account settings + </tp:docstring> </arg> <arg type="s" name="createdAccountId" direction="out"> - <tp:docstring> - A new account ID - </tp:docstring> + <tp:docstring> + A new account ID + </tp:docstring> </arg> </method> <method name="setAccountsOrder" tp:name-for-bindings="setAccountsOrder"> <tp:docstring> - Update the accounts order. - <tp:rationale>When placing a call, the first registered account in the list is used.</tp:rationale> + Update the accounts order. + <tp:rationale>When placing a call, the first registered account in the list is used.</tp:rationale> </tp:docstring> <arg type="s" name="order" direction="in"> - <tp:docstring> - An ordered list of account IDs, delimited by '/' - </tp:docstring> + <tp:docstring> + An ordered list of account IDs, delimited by '/' + </tp:docstring> </arg> </method> <method name="removeAccount" tp:name-for-bindings="removeAccount"> - <tp:docstring> - Remove an existing account. When removed, the signal <tp:member-ref>accountsChanged</tp:member-ref> is emitted. The clients must then call <tp:member-ref>getAccountList</tp:member-ref> to update their internal data structure. - </tp:docstring> - <arg type="s" name="accoundID" direction="in"> - <tp:docstring> - The account to remove, identified by its ID - </tp:docstring> - </arg> + <tp:docstring> + Remove an existing account. When removed, the signal <tp:member-ref>accountsChanged</tp:member-ref> is emitted. The clients must then call <tp:member-ref>getAccountList</tp:member-ref> to update their internal data structure. + </tp:docstring> + <arg type="s" name="accoundID" direction="in"> + <tp:docstring> + The account to remove, identified by its ID + </tp:docstring> + </arg> </method> <method name="getAccountList" tp:name-for-bindings="getAccountList"> - <tp:docstring> - Get a list of all created accounts, as stored by the core. - </tp:docstring> + <tp:docstring> + Get a list of all created accounts, as stored by the core. + </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> - <tp:docstring> - A list of account IDs - </tp:docstring> + <tp:docstring> + A list of account IDs + </tp:docstring> </arg> </method> @@ -268,15 +254,15 @@ @param[in] input accountID --> <arg type="s" name="accountID" direction="in"> - <tp:docstring> - The account ID - </tp:docstring> + <tp:docstring> + The account ID + </tp:docstring> </arg> <arg type="i" name="expire" direction="in"> - <tp:docstring> - <p>To register, expire must be 1.</p> - <p>To un-register, expire must be 0.</p> - </tp:docstring> + <tp:docstring> + <p>To register, expire must be 1.</p> + <p>To un-register, expire must be 0.</p> + </tp:docstring> </arg> </method> @@ -285,14 +271,13 @@ </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> - <tp:docstring> - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getVersion" tp:name-for-bindings="getVersion"> <tp:docstring> - Return SFLphone-daemon version </tp:docstring> <arg type="s" name="version" direction="out"> <tp:docstring> @@ -302,19 +287,16 @@ <method name="getRingtoneList" tp:name-for-bindings="getRingtoneList"> <tp:docstring> - Return a list of valid Sun's .au sound file used - as ringtones. </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> - <tp:docstring> - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getPlaybackDeviceList" tp:name-for-bindings="getPlaybackDeviceList"> <tp:docstring> - Provide a list of playback device from ALSA </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> @@ -325,7 +307,6 @@ <method name="getRecordDeviceList" tp:name-for-bindings="getRecordDeviceList"> <tp:docstring> - Provide a list of record device from ALSA </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> @@ -336,8 +317,8 @@ <method name="isRingtoneEnabled" tp:name-for-bindings="isRingtoneEnabled"> <tp:docstring> - Return true if ringtone is enabled, false otherwise </tp:docstring> + <arg type="s" name="accountID" direction="in" /> <arg type="i" name="bool" direction="out"> <tp:docstring> </tp:docstring> @@ -346,28 +327,27 @@ <method name="ringtoneEnabled" tp:name-for-bindings="ringtoneEnabled"> <tp:docstring> - Unused </tp:docstring> + <arg type="s" name="accountID" direction="in"/> </method> <method name="getRingtoneChoice" tp:name-for-bindings="getRingtoneChoice"> <tp:docstring> - Get current ringtone .au file selected </tp:docstring> + <arg type="s" name="accountID" direction="in"/> <arg type="s" name="tone" direction="out"> - <tp:docstring> - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="setRingtoneChoice" tp:name-for-bindings="setRingtoneChoice"> <tp:docstring> - Set current ringtone .au file from list acquired using <tp:member-ref>getAccountList</tp:member-ref> </tp:docstring> + <arg type="s" name="accountID" direction="in"/> <arg type="s" name="tone" direction="in"> - <tp:docstring> - A valid .au file path - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> @@ -476,16 +456,7 @@ </arg> </method> - <method name="setInputAudioPlugin" tp:name-for-bindings="setInputAudioPlugin"> - <tp:docstring> - </tp:docstring> - <arg type="s" name="audioPlugin" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setOutputAudioPlugin" tp:name-for-bindings="setOutputAudioPlugin"> + <method name="setAudioPlugin" tp:name-for-bindings="setAudioPlugin"> <tp:docstring> </tp:docstring> <arg type="s" name="audioPlugin" direction="in"> @@ -633,20 +604,6 @@ </arg> </method> - <method name="setNotify" tp:name-for-bindings="setNotify"> - <tp:docstring> - </tp:docstring> - </method> - - <method name="getNotify" tp:name-for-bindings="getNotify"> - <tp:docstring> - </tp:docstring> - <arg type="i" name="level" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - <method name="setMailNotify" tp:name-for-bindings="setMailNotify"> <tp:docstring> </tp:docstring> @@ -661,69 +618,6 @@ </arg> </method> - <method name="getDialpad" tp:name-for-bindings="getDialpad"> - <tp:docstring> - </tp:docstring> - <arg type="i" name="state" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setDialpad" tp:name-for-bindings="setDialpad"> - <tp:docstring> - </tp:docstring> - <arg type="b" name="display" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="getSearchbar" tp:name-for-bindings="getSearchbar"> - <tp:docstring> - </tp:docstring> - <arg type="i" name="state" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setSearchbar" tp:name-for-bindings="setSearchbar"> - <tp:docstring> - </tp:docstring> - </method> - - <method name="setHistoryEnabled" tp:name-for-bindings="setHistoryEnabled"> - <tp:docstring> - </tp:docstring> - </method> - - <method name="getHistoryEnabled" tp:name-for-bindings="getHistoryEnabled"> - <tp:docstring> - </tp:docstring> - <arg type="s" name="state" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="getVolumeControls" tp:name-for-bindings="getVolumeControls"> - <tp:docstring> - </tp:docstring> - <arg type="i" name="state" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setVolumeControls" tp:name-for-bindings="setVolumeControls"> - <tp:docstring> - </tp:docstring> - <arg type="b" name="display" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - </method> <method name="getHistoryLimit" tp:name-for-bindings="getHistoryLimit"> <tp:docstring> @@ -743,137 +637,6 @@ </arg> </method> - <method name="startHidden" tp:name-for-bindings="startHidden"> - <tp:docstring> - </tp:docstring> - </method> - - <method name="isStartHidden" tp:name-for-bindings="isStartHidden"> - <tp:docstring> - </tp:docstring> - <arg type="i" name="state" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="popupMode" tp:name-for-bindings="popupMode"> - <tp:docstring> - </tp:docstring> - <arg type="i" name="state" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="switchPopupMode" tp:name-for-bindings="switchPopupMode"> - <tp:docstring> - </tp:docstring> - </method> - - <method name="getWindowWidth" tp:name-for-bindings="getWindowWidth"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="width" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="getWindowHeight" tp:name-for-bindings="getWindowHeight"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="height" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setWindowWidth" tp:name-for-bindings="setWindowWidth"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="width" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setWindowHeight" tp:name-for-bindings="setWindowHeight"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="height" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="getWindowPositionX" tp:name-for-bindings="getWindowPositionX"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="posX" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setWindowPositionX" tp:name-for-bindings="setWindowPositionX"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="posX" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="getWindowPositionY" tp:name-for-bindings="getWindowPositionY"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="posY" direction="out"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="setWindowPositionY" tp:name-for-bindings="setWindowPositionY"> - <tp:docstring> - Unused - </tp:docstring> - <arg type="i" name="posY" direction="in"> - <tp:docstring> - </tp:docstring> - </arg> - </method> - - <method name="enableStatusIcon" tp:name-for-bindings="enableStatusIcon"> - <tp:docstring> - Allow SFLphone icon to be displayed in system tray - </tp:docstring> - <arg type="s" name="value" direction="in"> - <tp:docstring> - true/false - </tp:docstring> - </arg> - </method> - - <method name="isStatusIconEnabled" tp:name-for-bindings="isStatusIconEnabled"> - <tp:docstring> - Test if SFLphone icon is displayed in system tray. - </tp:docstring> - <arg type="s" name="value" direction="out"> - <tp:docstring> - true/false - </tp:docstring> - </arg> - </method> - - <!-- Addressbook configuration --> <method name="getAddressbookSettings" tp:name-for-bindings="getAddressbookSettings"> <tp:docstring> @@ -952,162 +715,110 @@ </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="MapStringString"/> <arg type="a{ss}" name="entries" direction="in"> - <tp:docstring> - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <signal name="accountsChanged" tp:name-for-bindings="accountsChanged"> - <tp:docstring> - Signal emited on account changes. Clients should update - all account status with <tp:member-ref>getAccountDetails</tp:member-ref> - iterating over the list provided by <tp:member-ref>getAccountList</tp:member-ref> - </tp:docstring> </signal> <signal name="errorAlert" tp:name-for-bindings="errorAlert"> <arg type="i" name="code"> - <tp:docstring> - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </signal> <!-- TLS Methods --> <method name="getSupportedTlsMethod" tp:name-for-bindings="getSupportedTlsMethod"> <tp:docstring> - Provide a list of supported TLS method </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> - <tp:docstring> - A list of TLS method: (TLSv1, SSLv1, SSLv2, - SSLv3, SSLv23) - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getTlsSettingsDefault" tp:name-for-bindings="getTlsSettingsDefault"> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/> <tp:docstring> - Get default TLS setting for new accounts </tp:docstring> <arg type="a{ss}" name="details" direction="out"> - <tp:docstring> - A hash table containing details. Refer - to <tp:member-ref>getTlsSettings</tp:member-ref> - for possible keys - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getTlsSettings" tp:name-for-bindings="getTlsSettings"> <tp:docstring> - Get current TLS setting for a specific account </tp:docstring> - <arg type="s" name="accountID" direction="in"> - <tp:docstring> - The account ID - </tp:docstring> - </arg> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/> <arg type="a{ss}" name="details" direction="out"> - <tp:docstring> - A hash table containing details with key: - <ul> - <li>"TLS.listenerPort": valid numerical port</li> - <li>"TLS.enable": true/false</li> - <li>"TLS.certificateListFile": A valid path to - a .pem file containing CA certificate</li> - <li>"TLS.certificateFile": A valid path to a - file containing the public end-point - certificate (optional)</li> - <li>"TLS.privateKeyFile": A valid path to a - file containing the public end-point private - key (optional)</li> - <li>"TLS.password": Public end-point private - key password (optional)</li> - <li>"TLS.method": (TLSv1, SSLv1, SSLv2, - SSLv3, SSLv23)</li> - </ul> - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="setTlsSettings" tp:name-for-bindings="setTlsSettings"> <tp:docstring> - Update TLS setting for a specific account </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="MapStringString"/> - <arg type="s" name="accountID" direction="in"> - <tp:docstring> - The account ID - </tp:docstring> - </arg> <arg type="a{ss}" name="details" direction="in"> - <tp:docstring> - A hash table containing details. Refer - to <tp:member-ref>getTlsSettings</tp:member-ref> - for possible keys. - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getAddrFromInterfaceName" tp:name-for-bindings="getAddrFromInterfaceName"> <tp:docstring> - Resolve interface IPv4 address provided its name. </tp:docstring> <arg type="s" name="interface" direction="in"> - <tp:docstring> - Interface name - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> <arg type="s" name="address" direction="out"> - <tp:docstring> - Interface IPv4 address - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getAllIpInterface" tp:name-for-bindings="getAllIpInterface"> <tp:docstring> - Provide a list of IP interface's IPv4 address. </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> - <tp:docstring> - A list of interface's IPv4 address - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getAllIpInterfaceByName" tp:name-for-bindings="getAllIpInterfaceByName"> <tp:docstring> - Provide a list of IP interface's name: default - (0.0.0.0), lo, eth0 ... </tp:docstring> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"> - <tp:docstring> - A list of interface's name - </tp:docstring> + <tp:docstring> + </tp:docstring> </arg> </method> <method name="getShortcuts" tp:name-for-bindings="getShortcuts"> - <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringInt"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/> <tp:docstring> </tp:docstring> - <arg type="a{si}" name="shortcutsMap" direction="out"> + <arg type="a{ss}" name="shortcutsMap" direction="out"> <tp:docstring> </tp:docstring> </arg> </method> <method name="setShortcuts" tp:name-for-bindings="setShortcuts"> - <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="MapStringInt"/> + <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="MapStringString"/> <tp:docstring> </tp:docstring> - <arg type="a{si}" name="shortcutsMap" direction="in"> + <arg type="a{ss}" name="shortcutsMap" direction="in"> <tp:docstring> </tp:docstring> </arg> diff --git a/sflphone-common/src/dbus/configurationmanager.cpp b/sflphone-common/src/dbus/configurationmanager.cpp index 63cab38ab4ba0656b5f4b23e7f809ec30a033969..c14c491bb55e2b18b4777da63bcd2944244be96c 100644 --- a/sflphone-common/src/dbus/configurationmanager.cpp +++ b/sflphone-common/src/dbus/configurationmanager.cpp @@ -35,6 +35,7 @@ #include <sstream> #include "../manager.h" #include "sip/sipvoiplink.h" +#include "sip/sipaccount.h" const char* ConfigurationManager::SERVER_PATH = "/org/sflphone/SFLphone/ConfigurationManager"; @@ -52,6 +53,8 @@ ConfigurationManager::ConfigurationManager (DBus::Connection& connection) : std::map<std::string, std::string> ConfigurationManager::getAccountDetails ( const std::string& accountID) { + + _debug ("ConfigurationManager: get account details %s", accountID.c_str()); return Manager::instance().getAccountDetails (accountID); } @@ -60,6 +63,7 @@ std::map<std::string, std::string> ConfigurationManager::getTlsSettingsDefault ( { std::map<std::string, std::string> tlsSettingsDefault; + tlsSettingsDefault.insert (std::pair<std::string, std::string> ( TLS_LISTENER_PORT, DEFAULT_SIP_TLS_PORT)); tlsSettingsDefault.insert (std::pair<std::string, std::string> ( @@ -95,37 +99,28 @@ std::map<std::string, std::string> ConfigurationManager::getIp2IpDetails (void) std::map<std::string, std::string> ip2ipAccountDetails; - ip2ipAccountDetails.insert (std::pair<std::string, std::string> (ACCOUNT_ID, - IP2IP_PROFILE)); - ip2ipAccountDetails.insert (std::pair<std::string, std::string> ( - SRTP_KEY_EXCHANGE, Manager::instance().getConfigString ( - IP2IP_PROFILE, SRTP_KEY_EXCHANGE))); - ip2ipAccountDetails.insert (std::pair<std::string, std::string> (SRTP_ENABLE, - Manager::instance().getConfigString (IP2IP_PROFILE, SRTP_ENABLE))); - ip2ipAccountDetails.insert (std::pair<std::string, std::string> ( - SRTP_RTP_FALLBACK, Manager::instance().getConfigString ( - IP2IP_PROFILE, SRTP_RTP_FALLBACK))); - ip2ipAccountDetails.insert (std::pair<std::string, std::string> ( - ZRTP_DISPLAY_SAS, Manager::instance().getConfigString ( - IP2IP_PROFILE, ZRTP_DISPLAY_SAS))); - ip2ipAccountDetails.insert (std::pair<std::string, std::string> ( - ZRTP_HELLO_HASH, Manager::instance().getConfigString (IP2IP_PROFILE, - ZRTP_HELLO_HASH))); - ip2ipAccountDetails.insert (std::pair<std::string, std::string> ( - ZRTP_NOT_SUPP_WARNING, Manager::instance().getConfigString ( - IP2IP_PROFILE, ZRTP_NOT_SUPP_WARNING))); - ip2ipAccountDetails.insert (std::pair<std::string, std::string> ( - ZRTP_DISPLAY_SAS_ONCE, Manager::instance().getConfigString ( - IP2IP_PROFILE, ZRTP_DISPLAY_SAS_ONCE))); - - ip2ipAccountDetails.insert (std::pair<std::string, std::string> ( - LOCAL_INTERFACE, Manager::instance().getConfigString (IP2IP_PROFILE, - LOCAL_INTERFACE))); - ip2ipAccountDetails.insert (std::pair<std::string, std::string> (LOCAL_PORT, - Manager::instance().getConfigString (IP2IP_PROFILE, LOCAL_PORT))); + SIPAccount *sipaccount = (SIPAccount *) Manager::instance().getAccount (IP2IP_PROFILE); + + if (!sipaccount) { + _error ("ConfigurationManager: could not find account"); + return ip2ipAccountDetails; + } + + ip2ipAccountDetails.insert (std::pair<std::string, std::string> (ACCOUNT_ID, IP2IP_PROFILE)); + ip2ipAccountDetails.insert (std::pair<std::string, std::string> (SRTP_KEY_EXCHANGE, sipaccount->getSrtpKeyExchange())); + ip2ipAccountDetails.insert (std::pair<std::string, std::string> (SRTP_ENABLE, sipaccount->getSrtpEnable() ? "true" : "false")); + ip2ipAccountDetails.insert (std::pair<std::string, std::string> (SRTP_RTP_FALLBACK, sipaccount->getSrtpFallback() ? "true" : "false")); + ip2ipAccountDetails.insert (std::pair<std::string, std::string> (ZRTP_DISPLAY_SAS, sipaccount->getZrtpDisplaySas() ? "true" : "false")); + ip2ipAccountDetails.insert (std::pair<std::string, std::string> (ZRTP_HELLO_HASH, sipaccount->getZrtpHelloHash() ? "true" : "false")); + ip2ipAccountDetails.insert (std::pair<std::string, std::string> (ZRTP_NOT_SUPP_WARNING, sipaccount->getZrtpNotSuppWarning() ? "true" : "false")); + ip2ipAccountDetails.insert (std::pair<std::string, std::string> (ZRTP_DISPLAY_SAS_ONCE, sipaccount->getZrtpDiaplaySasOnce() ? "true" : "false")); + ip2ipAccountDetails.insert (std::pair<std::string, std::string> (LOCAL_INTERFACE, sipaccount->getLocalInterface())); + std::stringstream portstr; + portstr << sipaccount->getLocalPort(); + ip2ipAccountDetails.insert (std::pair<std::string, std::string> (LOCAL_PORT, portstr.str())); std::map<std::string, std::string> tlsSettings; - tlsSettings = getTlsSettings (IP2IP_PROFILE); + tlsSettings = getTlsSettings(); std::copy (tlsSettings.begin(), tlsSettings.end(), std::inserter ( ip2ipAccountDetails, ip2ipAccountDetails.end())); @@ -139,68 +134,50 @@ void ConfigurationManager::setIp2IpDetails (const std::map<std::string, std::map<std::string, std::string> map_cpy = details; std::map<std::string, std::string>::iterator it; - it = map_cpy.find (LOCAL_INTERFACE); + SIPAccount *sipaccount = (SIPAccount *) Manager::instance().getAccount (IP2IP_PROFILE); - if (it != details.end()) { - Manager::instance().setConfig (IP2IP_PROFILE, LOCAL_INTERFACE, - it->second); + if (!sipaccount) { + _error ("ConfigurationManager: could not find account"); } + + it = map_cpy.find (LOCAL_INTERFACE); + + if (it != details.end()) sipaccount->setLocalInterface (it->second); + it = map_cpy.find (LOCAL_PORT); - if (it != details.end()) { - Manager::instance().setConfig (IP2IP_PROFILE, LOCAL_PORT, it->second); - } + if (it != details.end()) sipaccount->setLocalPort (atoi (it->second.data())); it = map_cpy.find (SRTP_ENABLE); - if (it != details.end()) { - Manager::instance().setConfig (IP2IP_PROFILE, SRTP_ENABLE, it->second); - } + if (it != details.end()) sipaccount->setSrtpEnable ( (it->second == "true")); it = map_cpy.find (SRTP_RTP_FALLBACK); - if (it != details.end()) { - Manager::instance().setConfig (IP2IP_PROFILE, SRTP_RTP_FALLBACK, - it->second); - } + if (it != details.end()) sipaccount->setSrtpFallback ( (it->second == "true")); it = map_cpy.find (SRTP_KEY_EXCHANGE); - if (it != details.end()) { - Manager::instance().setConfig (IP2IP_PROFILE, SRTP_KEY_EXCHANGE, - it->second); - } + if (it != details.end()) sipaccount->setSrtpKeyExchange (it->second); it = map_cpy.find (ZRTP_DISPLAY_SAS); - if (it != details.end()) { - Manager::instance().setConfig (IP2IP_PROFILE, ZRTP_DISPLAY_SAS, - it->second); - } + if (it != details.end()) sipaccount->setZrtpDisplaySas ( (it->second == "true")); it = map_cpy.find (ZRTP_NOT_SUPP_WARNING); - if (it != details.end()) { - Manager::instance().setConfig (IP2IP_PROFILE, ZRTP_NOT_SUPP_WARNING, - it->second); - } + if (it != details.end()) sipaccount->setZrtpNotSuppWarning ( (it->second == "true")); it = map_cpy.find (ZRTP_HELLO_HASH); - if (it != details.end()) { - Manager::instance().setConfig (IP2IP_PROFILE, ZRTP_HELLO_HASH, - it->second); - } + if (it != details.end()) sipaccount->setZrtpHelloHash ( (it->second == "true")); it = map_cpy.find (ZRTP_DISPLAY_SAS_ONCE); - if (it != details.end()) { - Manager::instance().setConfig (IP2IP_PROFILE, ZRTP_DISPLAY_SAS_ONCE, - it->second); - } + if (it != details.end()) sipaccount->setZrtpDiaplaySasOnce ( (it->second == "true")); - setTlsSettings (IP2IP_PROFILE, details); + setTlsSettings (details); Manager::instance().saveConfig(); @@ -212,134 +189,100 @@ void ConfigurationManager::setIp2IpDetails (const std::map<std::string, } -std::map<std::string, std::string> ConfigurationManager::getTlsSettings ( - const std::string& section) +std::map<std::string, std::string> ConfigurationManager::getTlsSettings() { + std::map<std::string, std::string> tlsSettings; - tlsSettings.insert (std::pair<std::string, std::string> (TLS_LISTENER_PORT, - Manager::instance().getConfigString (section, TLS_LISTENER_PORT))); - tlsSettings.insert (std::pair<std::string, std::string> (TLS_ENABLE, - Manager::instance().getConfigString (section, TLS_ENABLE))); - tlsSettings.insert (std::pair<std::string, std::string> (TLS_CA_LIST_FILE, - Manager::instance().getConfigString (section, TLS_CA_LIST_FILE))); - tlsSettings.insert (std::pair<std::string, std::string> ( - TLS_CERTIFICATE_FILE, Manager::instance().getConfigString (section, - TLS_CERTIFICATE_FILE))); - tlsSettings.insert (std::pair<std::string, std::string> ( - TLS_PRIVATE_KEY_FILE, Manager::instance().getConfigString (section, - TLS_PRIVATE_KEY_FILE))); - tlsSettings.insert (std::pair<std::string, std::string> (TLS_PASSWORD, - Manager::instance().getConfigString (section, TLS_PASSWORD))); - tlsSettings.insert (std::pair<std::string, std::string> (TLS_METHOD, - Manager::instance().getConfigString (section, TLS_METHOD))); - tlsSettings.insert (std::pair<std::string, std::string> (TLS_CIPHERS, - Manager::instance().getConfigString (section, TLS_CIPHERS))); - tlsSettings.insert (std::pair<std::string, std::string> (TLS_SERVER_NAME, - Manager::instance().getConfigString (section, TLS_SERVER_NAME))); - tlsSettings.insert (std::pair<std::string, std::string> (TLS_VERIFY_SERVER, - Manager::instance().getConfigString (section, TLS_VERIFY_SERVER))); - tlsSettings.insert (std::pair<std::string, std::string> (TLS_VERIFY_CLIENT, - Manager::instance().getConfigString (section, TLS_VERIFY_CLIENT))); - tlsSettings.insert (std::pair<std::string, std::string> ( - TLS_REQUIRE_CLIENT_CERTIFICATE, - Manager::instance().getConfigString (section, - TLS_REQUIRE_CLIENT_CERTIFICATE))); - tlsSettings.insert (std::pair<std::string, std::string> ( - TLS_NEGOTIATION_TIMEOUT_SEC, Manager::instance().getConfigString ( - section, TLS_NEGOTIATION_TIMEOUT_SEC))); - tlsSettings.insert (std::pair<std::string, std::string> ( - TLS_NEGOTIATION_TIMEOUT_MSEC, Manager::instance().getConfigString ( - section, TLS_NEGOTIATION_TIMEOUT_MSEC))); + SIPAccount *sipaccount = (SIPAccount *) Manager::instance().getAccount (IP2IP_PROFILE); + + if (!sipaccount) + return tlsSettings; + + std::stringstream portstr; + portstr << sipaccount->getTlsListenerPort(); + tlsSettings.insert (std::pair<std::string, std::string> (TLS_LISTENER_PORT, portstr.str())); + tlsSettings.insert (std::pair<std::string, std::string> (TLS_ENABLE, sipaccount->getTlsEnable())); + tlsSettings.insert (std::pair<std::string, std::string> (TLS_CA_LIST_FILE, sipaccount->getTlsCaListFile())); + tlsSettings.insert (std::pair<std::string, std::string> (TLS_CERTIFICATE_FILE, sipaccount->getTlsCertificateFile())); + tlsSettings.insert (std::pair<std::string, std::string> (TLS_PRIVATE_KEY_FILE, sipaccount->getTlsPrivateKeyFile())); + tlsSettings.insert (std::pair<std::string, std::string> (TLS_PASSWORD, sipaccount->getTlsPassword())); + tlsSettings.insert (std::pair<std::string, std::string> (TLS_METHOD, sipaccount->getTlsMethod())); + tlsSettings.insert (std::pair<std::string, std::string> (TLS_CIPHERS, sipaccount->getTlsCiphers())); + tlsSettings.insert (std::pair<std::string, std::string> (TLS_SERVER_NAME, sipaccount->getTlsServerName())); + tlsSettings.insert (std::pair<std::string, std::string> (TLS_VERIFY_SERVER, sipaccount->getTlsVerifyServer() ? "true" : "false")); + tlsSettings.insert (std::pair<std::string, std::string> (TLS_VERIFY_CLIENT, sipaccount->getTlsVerifyClient() ? "true" : "false")); + tlsSettings.insert (std::pair<std::string, std::string> (TLS_REQUIRE_CLIENT_CERTIFICATE, sipaccount->getTlsRequireClientCertificate() ? "true" : "false")); + tlsSettings.insert (std::pair<std::string, std::string> (TLS_NEGOTIATION_TIMEOUT_SEC, sipaccount->getTlsNegotiationTimeoutSec())); + tlsSettings.insert (std::pair<std::string, std::string> (TLS_NEGOTIATION_TIMEOUT_MSEC, sipaccount->getTlsNegotiationTimeoutMsec())); + return tlsSettings; } -void ConfigurationManager::setTlsSettings (const std::string& section, - const std::map<std::string, std::string>& details) +void ConfigurationManager::setTlsSettings (const std::map<std::string, std::string>& details) { + std::map<std::string, std::string> map_cpy = details; std::map<std::string, std::string>::iterator it; - it = map_cpy.find (TLS_LISTENER_PORT); + SIPAccount * sipaccount = (SIPAccount *) Manager::instance().getAccount (IP2IP_PROFILE); - if (it != details.end()) { - Manager::instance().setConfig (section, TLS_LISTENER_PORT, it->second); + if (!sipaccount) { + _debug ("ConfigurationManager: Error: No valid account in set TLS settings"); + return; } + it = map_cpy.find (TLS_LISTENER_PORT); + + if (it != details.end()) sipaccount->setTlsListenerPort (atoi (it->second.data())); + it = map_cpy.find (TLS_ENABLE); - if (it != details.end()) { - Manager::instance().setConfig (section, TLS_ENABLE, it->second); - } + if (it != details.end()) sipaccount->setTlsEnable (it->second); it = map_cpy.find (TLS_CA_LIST_FILE); - if (it != map_cpy.end()) { - Manager::instance().setConfig (section, TLS_CA_LIST_FILE, it->second); - } + if (it != map_cpy.end()) sipaccount->setTlsCaListFile (it->second); it = map_cpy.find (TLS_CERTIFICATE_FILE); - if (it != map_cpy.end()) { - Manager::instance().setConfig (section, TLS_CERTIFICATE_FILE, it->second); - } + if (it != map_cpy.end()) sipaccount->setTlsCertificateFile (it->second); it = map_cpy.find (TLS_PRIVATE_KEY_FILE); - if (it != map_cpy.end()) { - Manager::instance().setConfig (section, TLS_PRIVATE_KEY_FILE, it->second); - } + if (it != map_cpy.end()) sipaccount->setTlsPrivateKeyFile (it->second); it = map_cpy.find (TLS_PASSWORD); - if (it != map_cpy.end()) { - Manager::instance().setConfig (section, TLS_PASSWORD, it->second); - } + if (it != map_cpy.end()) sipaccount->setTlsPassword (it->second); it = map_cpy.find (TLS_METHOD); - if (it != map_cpy.end()) { - Manager::instance().setConfig (section, TLS_METHOD, it->second); - } + if (it != map_cpy.end()) sipaccount->setTlsMethod (it->second); it = map_cpy.find (TLS_CIPHERS); - if (it != map_cpy.end()) { - Manager::instance().setConfig (section, TLS_CIPHERS, it->second); - } + if (it != map_cpy.end()) sipaccount->setTlsCiphers (it->second); it = map_cpy.find (TLS_SERVER_NAME); - if (it != map_cpy.end()) { - Manager::instance().setConfig (section, TLS_SERVER_NAME, it->second); - } + if (it != map_cpy.end()) sipaccount->setTlsServerName (it->second); it = map_cpy.find (TLS_VERIFY_CLIENT); - if (it != map_cpy.end()) { - Manager::instance().setConfig (section, TLS_VERIFY_CLIENT, it->second); - } + if (it != map_cpy.end()) sipaccount->setTlsVerifyClient ( (it->second == "true") ? true : false); it = map_cpy.find (TLS_REQUIRE_CLIENT_CERTIFICATE); - if (it != map_cpy.end()) { - Manager::instance().setConfig (section, TLS_REQUIRE_CLIENT_CERTIFICATE, - it->second); - } + if (it != map_cpy.end()) sipaccount->setTlsRequireClientCertificate ( (it->second == "true") ? true : false); it = map_cpy.find (TLS_NEGOTIATION_TIMEOUT_SEC); - if (it != map_cpy.end()) { - Manager::instance().setConfig (section, TLS_NEGOTIATION_TIMEOUT_SEC, - it->second); - } + if (it != map_cpy.end()) sipaccount->setTlsNegotiationTimeoutSec (it->second); it = map_cpy.find (TLS_NEGOTIATION_TIMEOUT_MSEC); - if (it != map_cpy.end()) { - Manager::instance().setConfig (section, TLS_NEGOTIATION_TIMEOUT_MSEC, - it->second); - } + if (it != map_cpy.end()) sipaccount->setTlsNegotiationTimeoutMsec (it->second); Manager::instance().saveConfig(); @@ -352,27 +295,35 @@ std::map<std::string, std::string> ConfigurationManager::getCredential ( const std::string& accountID, const int32_t& index) { - std::string credentialIndex; - std::stringstream streamOut; - streamOut << index; - credentialIndex = streamOut.str(); - - std::string section = std::string ("Credential") + std::string (":") - + accountID + std::string (":") + credentialIndex; + Account *account = Manager::instance().getAccount (accountID); std::map<std::string, std::string> credentialInformation; - std::string username = Manager::instance().getConfigString (section, - USERNAME); - std::string password = Manager::instance().getConfigString (section, - PASSWORD); - std::string realm = Manager::instance().getConfigString (section, REALM); - - credentialInformation.insert (std::pair<std::string, std::string> (USERNAME, - username)); - credentialInformation.insert (std::pair<std::string, std::string> (PASSWORD, - password)); - credentialInformation.insert (std::pair<std::string, std::string> (REALM, - realm)); + + if (account->getType() != "SIP") + return credentialInformation; + + SIPAccount *sipaccount = (SIPAccount *) account; + + + if (index == 0) { + std::string username = sipaccount->getUsername(); + std::string password = sipaccount->getPassword(); + std::string realm = sipaccount->getRealm(); + + credentialInformation.insert (std::pair<std::string, std::string> (USERNAME, username)); + credentialInformation.insert (std::pair<std::string, std::string> (PASSWORD, password)); + credentialInformation.insert (std::pair<std::string, std::string> (REALM, realm)); + } else { + + // TODO: implement for extra credentials + std::string username = sipaccount->getUsername(); + std::string password = sipaccount->getPassword(); + std::string realm = sipaccount->getRealm(); + + credentialInformation.insert (std::pair<std::string, std::string> (USERNAME, username)); + credentialInformation.insert (std::pair<std::string, std::string> (PASSWORD, password)); + credentialInformation.insert (std::pair<std::string, std::string> (REALM, realm)); + } return credentialInformation; } @@ -380,16 +331,9 @@ std::map<std::string, std::string> ConfigurationManager::getCredential ( int32_t ConfigurationManager::getNumberOfCredential ( const std::string& accountID) { - return Manager::instance().getConfigInt (accountID, CONFIG_CREDENTIAL_NUMBER); -} -void ConfigurationManager::setNumberOfCredential (const std::string& accountID, - const int32_t& number) -{ - if (accountID != AccountNULL || !accountID.empty()) { - Manager::instance().setConfig (accountID, CONFIG_CREDENTIAL_NUMBER, - number); - } + SIPAccount *sipaccount = (SIPAccount *) Manager::instance().getAccount (accountID); + return sipaccount->getCredentialCount(); } void ConfigurationManager::setCredential (const std::string& accountID, @@ -461,8 +405,7 @@ std::vector<std::string> ConfigurationManager::getCodecList (void) std::vector<std::string> list; - CodecsMap codecs = - Manager::instance().getCodecDescriptorMap().getCodecsMap(); + CodecsMap codecs = Manager::instance().getCodecDescriptorMap().getCodecsMap(); CodecsMap::iterator iter = codecs.begin(); while (iter != codecs.end()) { @@ -558,14 +501,11 @@ std::vector<std::string> ConfigurationManager::getAudioPluginList() } -void ConfigurationManager::setInputAudioPlugin (const std::string& audioPlugin) +void ConfigurationManager::setAudioPlugin (const std::string& audioPlugin) { - return Manager::instance().setInputAudioPlugin (audioPlugin); -} + _debug ("ConfigurationManager: Set audio plugin %s", audioPlugin.c_str()); -void ConfigurationManager::setOutputAudioPlugin (const std::string& audioPlugin) -{ - return Manager::instance().setOutputAudioPlugin (audioPlugin); + return Manager::instance().setAudioPlugin (audioPlugin); } std::vector<std::string> ConfigurationManager::getAudioOutputDeviceList() @@ -605,6 +545,8 @@ int32_t ConfigurationManager::getAudioDeviceIndex (const std::string& name) std::string ConfigurationManager::getCurrentAudioOutputPlugin (void) { + _debug ("ConfigurationManager: Get audio plugin %s", Manager::instance().getCurrentAudioOutputPlugin().c_str()); + return Manager::instance().getCurrentAudioOutputPlugin(); } @@ -643,18 +585,12 @@ std::vector<std::string> ConfigurationManager::getRecordDeviceList() bool ConfigurationManager::isMd5CredentialHashing (void) { - bool isEnabled = Manager::instance().getConfigBool (PREFERENCES, - CONFIG_MD5HASH); - return isEnabled; + return Manager::instance().preferences.getMd5Hash(); } void ConfigurationManager::setMd5CredentialHashing (const bool& enabled) { - if (enabled) { - Manager::instance().setConfig (PREFERENCES, CONFIG_MD5HASH, TRUE_STR); - } else { - Manager::instance().setConfig (PREFERENCES, CONFIG_MD5HASH, FALSE_STR); - } + Manager::instance().preferences.setMd5Hash (enabled); } int32_t ConfigurationManager::isIax2Enabled (void) @@ -662,24 +598,24 @@ int32_t ConfigurationManager::isIax2Enabled (void) return Manager::instance().isIax2Enabled(); } -void ConfigurationManager::ringtoneEnabled (void) +void ConfigurationManager::ringtoneEnabled (const std::string& accountID) { - Manager::instance().ringtoneEnabled(); + Manager::instance().ringtoneEnabled (accountID); } -int32_t ConfigurationManager::isRingtoneEnabled (void) +int32_t ConfigurationManager::isRingtoneEnabled (const std::string& accountID) { - return Manager::instance().isRingtoneEnabled(); + return Manager::instance().isRingtoneEnabled (accountID); } -std::string ConfigurationManager::getRingtoneChoice (void) +std::string ConfigurationManager::getRingtoneChoice (const std::string& accountID) { - return Manager::instance().getRingtoneChoice(); + return Manager::instance().getRingtoneChoice (accountID); } -void ConfigurationManager::setRingtoneChoice (const std::string& tone) +void ConfigurationManager::setRingtoneChoice (const std::string& accountID, const std::string& tone) { - Manager::instance().setRingtoneChoice (tone); + Manager::instance().setRingtoneChoice (accountID, tone); } std::string ConfigurationManager::getRecordPath (void) @@ -692,35 +628,31 @@ void ConfigurationManager::setRecordPath (const std::string& recPath) Manager::instance().setRecordPath (recPath); } -int32_t ConfigurationManager::getDialpad (void) -{ - return Manager::instance().getDialpad(); +/* +int32_t ConfigurationManager::getDialpad(void) { + return Manager::instance().getDialpad(); } -void ConfigurationManager::setDialpad (const bool& display) -{ - Manager::instance().setDialpad (display); +void ConfigurationManager::setDialpad(const bool& display) { + Manager::instance().setDialpad(display); } -int32_t ConfigurationManager::getSearchbar (void) -{ - return Manager::instance().getSearchbar(); +int32_t ConfigurationManager::getSearchbar(void) { + return Manager::instance().getSearchbar(); } -void ConfigurationManager::setSearchbar (void) -{ - Manager::instance().setSearchbar(); +void ConfigurationManager::setSearchbar(void) { + Manager::instance().setSearchbar(); } -int32_t ConfigurationManager::getVolumeControls (void) -{ - return Manager::instance().getVolumeControls(); +int32_t ConfigurationManager::getVolumeControls(void) { + return Manager::instance().getVolumeControls(); } -void ConfigurationManager::setVolumeControls (const bool& display) -{ - Manager::instance().setVolumeControls (display); +void ConfigurationManager::setVolumeControls(const bool& display) { + Manager::instance().setVolumeControls(display); } +*/ int32_t ConfigurationManager::getHistoryLimit (void) { @@ -732,45 +664,39 @@ void ConfigurationManager::setHistoryLimit (const int32_t& days) Manager::instance().setHistoryLimit (days); } -void ConfigurationManager::setHistoryEnabled (void) -{ - Manager::instance().setHistoryEnabled(); +/* +void ConfigurationManager::setHistoryEnabled(void) { + Manager::instance().setHistoryEnabled(); } -std::string ConfigurationManager::getHistoryEnabled (void) -{ - return Manager::instance().getHistoryEnabled(); +std::string ConfigurationManager::getHistoryEnabled(void) { + return Manager::instance().getHistoryEnabled(); } -void ConfigurationManager::startHidden (void) -{ - Manager::instance().startHidden(); +void ConfigurationManager::startHidden(void) { + Manager::instance().startHidden(); } -int32_t ConfigurationManager::isStartHidden (void) -{ - return Manager::instance().isStartHidden(); +int32_t ConfigurationManager::isStartHidden(void) { + return Manager::instance().isStartHidden(); } -void ConfigurationManager::switchPopupMode (void) -{ - Manager::instance().switchPopupMode(); +void ConfigurationManager::switchPopupMode(void) { + Manager::instance().switchPopupMode(); } -int32_t ConfigurationManager::popupMode (void) -{ - return Manager::instance().popupMode(); +int32_t ConfigurationManager::popupMode(void) { + return Manager::instance().popupMode(); } -void ConfigurationManager::setNotify (void) -{ - Manager::instance().setNotify(); +void ConfigurationManager::setNotify(void) { + Manager::instance().setNotify(); } -int32_t ConfigurationManager::getNotify (void) -{ - return Manager::instance().getNotify(); +int32_t ConfigurationManager::getNotify(void) { + return Manager::instance().getNotify(); } +*/ void ConfigurationManager::setAudioManager (const int32_t& api) { @@ -879,96 +805,33 @@ std::vector<std::string> ConfigurationManager::getAllIpInterfaceByName (void) return vector; } -int32_t ConfigurationManager::getWindowWidth (void) -{ - - return Manager::instance().getConfigInt (PREFERENCES, WINDOW_WIDTH); -} - -int32_t ConfigurationManager::getWindowHeight (void) -{ - - return Manager::instance().getConfigInt (PREFERENCES, WINDOW_HEIGHT); -} - -void ConfigurationManager::setWindowWidth (const int32_t& width) -{ - - Manager::instance().setConfig (PREFERENCES, WINDOW_WIDTH, width); -} - -void ConfigurationManager::setWindowHeight (const int32_t& height) -{ - - Manager::instance().setConfig (PREFERENCES, WINDOW_HEIGHT, height); -} -int32_t ConfigurationManager::getWindowPositionX (void) +std::map<std::string, std::string> ConfigurationManager::getShortcuts() { - return Manager::instance().getConfigInt (PREFERENCES, WINDOW_POSITION_X); -} - -int32_t ConfigurationManager::getWindowPositionY (void) -{ - - return Manager::instance().getConfigInt (PREFERENCES, WINDOW_POSITION_Y); -} - -void ConfigurationManager::setWindowPositionX (const int32_t& posX) -{ - - Manager::instance().setConfig (PREFERENCES, WINDOW_POSITION_X, posX); -} - -void ConfigurationManager::setWindowPositionY (const int32_t& posY) -{ - - Manager::instance().setConfig (PREFERENCES, WINDOW_POSITION_Y, posY); -} - -std::map<std::string, int32_t> ConfigurationManager::getShortcuts() -{ - - std::map<std::string, int> shortcutsMap; - int shortcut; - - for (int i = 0; i < (int) shortcutsKeys.size(); i++) { - std::string key = shortcutsKeys.at (i); - shortcut = Manager::instance().getConfigInt ("Shortcuts", key); - shortcutsMap.insert (std::pair<std::string, int> (key, shortcut)); - } - - return shortcutsMap; + return Manager::instance().shortcutPreferences.getShortcuts(); } void ConfigurationManager::setShortcuts ( - const std::map<std::string, int32_t>& shortcutsMap) + const std::map<std::string, std::string>& shortcutsMap) { - std::map<std::string, int> map_cpy = shortcutsMap; - std::map<std::string, int>::iterator it; + std::map<std::string, std::string> map_cpy = shortcutsMap; + /* + std::map<std::string, std::string> map_cpy = shortcutsMap; + std::map<std::string, std::string>::iterator it; - for (int i = 0; i < (int) shortcutsKeys.size(); i++) { - std::string key = shortcutsKeys.at (i); - it = map_cpy.find (key); + for (int i = 0; i < (int)shortcutsKeys.size(); i++) { + std::string key = shortcutsKeys.at(i); + it = map_cpy.find(key); + if (it != shortcutsMap.end()) { - if (it != shortcutsMap.end()) { - Manager::instance().setConfig ("Shortcuts", key, it->second); - } - } + Manager::instance().setConfig("Shortcuts", key, it->second); + } + } + */ + Manager::instance().shortcutPreferences.setShortcuts (map_cpy); Manager::instance().saveConfig(); } -void ConfigurationManager::enableStatusIcon (const std::string& value) -{ - - Manager::instance ().setConfig (PREFERENCES, SHOW_STATUSICON, value); -} - -std::string ConfigurationManager::isStatusIconEnabled (void) -{ - - return Manager::instance ().getConfigString (PREFERENCES, SHOW_STATUSICON); -} diff --git a/sflphone-common/src/dbus/configurationmanager.h b/sflphone-common/src/dbus/configurationmanager.h index 7c351af08efb36b95ca6334f7fc6475a00d33805..469114922870232c8fceb5267f40dec3b71bd5cd 100644 --- a/sflphone-common/src/dbus/configurationmanager.h +++ b/sflphone-common/src/dbus/configurationmanager.h @@ -34,139 +34,116 @@ #ifndef CONFIGURATIONMANAGER_H #define CONFIGURATIONMANAGER_H +#pragma GCC diagnostic ignored "-Wignored-qualifiers" +#pragma GCC diagnostic ignored "-Wunused-parameter" #include "configurationmanager-glue.h" +#pragma GCC diagnostic warning "-Wignored-qualifiers" +#pragma GCC diagnostic warning "-Wunused-parameter" + #include <dbus-c++/dbus.h> class ConfigurationManager -: public org::sflphone::SFLphone::ConfigurationManager_adaptor, - public DBus::IntrospectableAdaptor, - public DBus::ObjectAdaptor + : public org::sflphone::SFLphone::ConfigurationManager_adaptor, + public DBus::IntrospectableAdaptor, + public DBus::ObjectAdaptor { -public: - - ConfigurationManager(DBus::Connection& connection); - static const char* SERVER_PATH; - -private: - std::vector<std::string> shortcutsKeys; - -public: - - std::map< std::string, std::string > getAccountDetails( const std::string& accountID ); - void setAccountDetails( const std::string& accountID, const std::map< std::string, std::string >& details ); - std::string addAccount( const std::map< std::string, std::string >& details ); - void removeAccount( const std::string& accoundID ); - void deleteAllCredential (const std::string& accountID); - std::vector< std::string > getAccountList( ); - void sendRegister( const std::string& accoundID , const int32_t& expire ); - - std::map< std::string, std::string > getTlsSettingsDefault (void); - void setIp2IpDetails(const std::map< std::string, std::string >& details); - std::map< std::string, std::string > getIp2IpDetails(void); - std::map< std::string, std::string > getCredential (const std::string& accountID, const int32_t& index); - int32_t getNumberOfCredential (const std::string& accountID); - void setCredential (const std::string& accountID, const int32_t& index, const std::map< std::string, std::string >& details); - void setNumberOfCredential (const std::string& accountID, const int32_t& number); - - std::vector< std::string > getCodecList(void); - std::vector< std::string > getSupportedTlsMethod(void); - std::vector< std::string > getCodecDetails( const int32_t& payload ); - std::vector< std::string > getActiveCodecList (const std::string& accountID); - void setActiveCodecList (const std::vector< std::string >& list, const std::string& accountID); - - std::vector< std::string > getAudioPluginList(); - void setInputAudioPlugin(const std::string& audioPlugin); - void setOutputAudioPlugin(const std::string& audioPlugin); - std::vector< std::string > getAudioOutputDeviceList(); - void setAudioOutputDevice(const int32_t& index); - void setAudioInputDevice(const int32_t& index); - void setAudioRingtoneDevice(const int32_t& index); - std::vector< std::string > getAudioInputDeviceList(); - std::vector< std::string > getCurrentAudioDevicesIndex(); - int32_t getAudioDeviceIndex(const std::string& name); - std::string getCurrentAudioOutputPlugin( void ); - std::string getEchoCancelState(void); - void setEchoCancelState(const std::string& state); - std::string getNoiseSuppressState(void); - void setNoiseSuppressState(const std::string& state); - - - std::vector< std::string > getToneLocaleList( ); - std::vector< std::string > getPlaybackDeviceList( ); - std::vector< std::string > getRecordDeviceList( ); - std::string getVersion( ); - std::vector< std::string > getRingtoneList( ); - int32_t getAudioManager( void ); - void setAudioManager( const int32_t& api ); - - bool isMd5CredentialHashing (void); - void setMd5CredentialHashing (const bool& enabled); - int32_t isIax2Enabled( void ); - int32_t isRingtoneEnabled( void ); - void ringtoneEnabled( void ); - std::string getRingtoneChoice( void ); - void setRingtoneChoice( const std::string& tone ); - std::string getRecordPath( void ); - void setRecordPath(const std::string& recPath ); - int32_t getDialpad( void ); - void setDialpad (const bool& display); - int32_t getSearchbar( void ); - - void setSearchbar( void ); - - void setHistoryLimit( const int32_t& days); - int32_t getHistoryLimit (void); - - void setHistoryEnabled (void); - std::string getHistoryEnabled (void); - - int32_t getVolumeControls( void ); - void setVolumeControls (const bool& display); - int32_t isStartHidden( void ); - void startHidden( void ); - int32_t popupMode( void ); - void switchPopupMode( void ); - int32_t getNotify( void ); - void setNotify( void ); - int32_t getMailNotify( void ); - void setMailNotify( void ); - - int32_t getWindowWidth (void); - int32_t getWindowHeight (void); - void setWindowWidth (const int32_t& width); - void setWindowHeight (const int32_t& height); - int32_t getWindowPositionX (void); - int32_t getWindowPositionY (void); - void setWindowPositionX (const int32_t& posX); - void setWindowPositionY (const int32_t& posY); - - void enableStatusIcon (const std::string&); - std::string isStatusIconEnabled (void); - - std::map<std::string, int32_t> getAddressbookSettings (void); - void setAddressbookSettings (const std::map<std::string, int32_t>& settings); - std::vector< std::string > getAddressbookList ( void ); - void setAddressbookList( const std::vector< std::string >& list ); - - void setAccountsOrder (const std::string& order); - - std::map<std::string, std::string> getHookSettings (void); - void setHookSettings (const std::map<std::string, std::string>& settings); - - std::map <std::string, std::string> getHistory (void); - void setHistory (const std::map <std::string, std::string>& entries); - - std::map<std::string, std::string> getTlsSettings(const std::string& accountID); - void setTlsSettings(const std::string& accountID, const std::map< std::string, std::string >& details); - - std::string getAddrFromInterfaceName(const std::string& interface); - - std::vector<std::string> getAllIpInterface(void); - std::vector<std::string> getAllIpInterfaceByName(void); - - std::map< std::string, int32_t > getShortcuts (); - void setShortcuts (const std::map< std::string, int32_t >& shortcutsMap); + public: + + ConfigurationManager (DBus::Connection& connection); + static const char* SERVER_PATH; + + private: + std::vector<std::string> shortcutsKeys; + + public: + + std::map< std::string, std::string > getAccountDetails (const std::string& accountID); + void setAccountDetails (const std::string& accountID, const std::map< std::string, std::string >& details); + std::string addAccount (const std::map< std::string, std::string >& details); + void removeAccount (const std::string& accoundID); + void deleteAllCredential (const std::string& accountID); + std::vector< std::string > getAccountList(); + void sendRegister (const std::string& accoundID , const int32_t& expire); + + std::map< std::string, std::string > getTlsSettingsDefault (void); + void setIp2IpDetails (const std::map< std::string, std::string >& details); + std::map< std::string, std::string > getIp2IpDetails (void); + std::map< std::string, std::string > getCredential (const std::string& accountID, const int32_t& index); + int32_t getNumberOfCredential (const std::string& accountID); + void setCredential (const std::string& accountID, const int32_t& index, const std::map< std::string, std::string >& details); + + std::vector< std::string > getCodecList (void); + std::vector< std::string > getSupportedTlsMethod (void); + std::vector< std::string > getCodecDetails (const int32_t& payload); + std::vector< std::string > getActiveCodecList (const std::string& accountID); + void setActiveCodecList (const std::vector< std::string >& list, const std::string& accountID); + + std::vector< std::string > getAudioPluginList(); + void setAudioPlugin (const std::string& audioPlugin); + std::vector< std::string > getAudioOutputDeviceList(); + void setAudioOutputDevice (const int32_t& index); + void setAudioInputDevice (const int32_t& index); + void setAudioRingtoneDevice (const int32_t& index); + std::vector< std::string > getAudioInputDeviceList(); + std::vector< std::string > getCurrentAudioDevicesIndex(); + int32_t getAudioDeviceIndex (const std::string& name); + std::string getCurrentAudioOutputPlugin (void); + std::string getEchoCancelState (void); + void setEchoCancelState (const std::string& state); + std::string getNoiseSuppressState (void); + void setNoiseSuppressState (const std::string& state); + + + std::vector< std::string > getToneLocaleList(); + std::vector< std::string > getPlaybackDeviceList(); + std::vector< std::string > getRecordDeviceList(); + std::string getVersion(); + std::vector< std::string > getRingtoneList(); + int32_t getAudioManager (void); + void setAudioManager (const int32_t& api); + + bool isMd5CredentialHashing (void); + void setMd5CredentialHashing (const bool& enabled); + int32_t isIax2Enabled (void); + int32_t isRingtoneEnabled (const std::string& accountID); + void ringtoneEnabled (const std::string& accountID); + std::string getRingtoneChoice (const std::string& accountID); + void setRingtoneChoice (const std::string& accountID, const std::string& tone); + std::string getRecordPath (void); + void setRecordPath (const std::string& recPath); + + + void setHistoryLimit (const int32_t& days); + int32_t getHistoryLimit (void); + + int32_t getMailNotify (void); + void setMailNotify (void); + + + std::map<std::string, int32_t> getAddressbookSettings (void); + void setAddressbookSettings (const std::map<std::string, int32_t>& settings); + std::vector< std::string > getAddressbookList (void); + void setAddressbookList (const std::vector< std::string >& list); + + void setAccountsOrder (const std::string& order); + + std::map<std::string, std::string> getHookSettings (void); + void setHookSettings (const std::map<std::string, std::string>& settings); + + std::map <std::string, std::string> getHistory (void); + void setHistory (const std::map <std::string, std::string>& entries); + + std::map<std::string, std::string> getTlsSettings (void); + void setTlsSettings (const std::map< std::string, std::string >& details); + + std::string getAddrFromInterfaceName (const std::string& interface); + + std::vector<std::string> getAllIpInterface (void); + std::vector<std::string> getAllIpInterfaceByName (void); + + std::map< std::string, std::string > getShortcuts (); + void setShortcuts (const std::map< std::string, std::string >& shortcutsMap); }; diff --git a/sflphone-common/src/dbus/contactmanager.h b/sflphone-common/src/dbus/contactmanager.h index 5611b41f9b8b0b90438955a0e332edcf3fa64574..a7a06b1bf73d061c1a7de27fcdec6b1a9adc4427 100644 --- a/sflphone-common/src/dbus/contactmanager.h +++ b/sflphone-common/src/dbus/contactmanager.h @@ -1,17 +1,17 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Guillaume Carmel-Archambault <guillaume.carmel-archambault@savoirfairelinux.com> - * + * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -27,29 +27,29 @@ * shall include the source code for the parts of OpenSSL used as well * as that of the covered work. */ - + #ifndef CONTACTMANAGER_H #define CONTACTMANAGER_H #include "contactmanager-glue.h" #include <dbus-c++/dbus.h> - + class ContactManager -: public org::sflphone::SFLphone::ContactManager_adaptor, - public DBus::IntrospectableAdaptor, - public DBus::ObjectAdaptor + : public org::sflphone::SFLphone::ContactManager_adaptor, + public DBus::IntrospectableAdaptor, + public DBus::ObjectAdaptor { -public: + public: - ContactManager(DBus::Connection& connection); - static const char* SERVER_PATH; + ContactManager (DBus::Connection& connection); + static const char* SERVER_PATH; -public: - std::map< std::string, std::string > getContacts( const std::string& accountID ); - void setContacts( const std::string& accountID, const std::map< std::string, std::string >& details ); - void setPresence( const std::string& accountID, const std::string& presence, const std::string& additionalInfo ); - void setContactPresence( const std::string& accountID, const std::string& presence, const std::string& additionalInfo ); + public: + std::map< std::string, std::string > getContacts (const std::string& accountID); + void setContacts (const std::string& accountID, const std::map< std::string, std::string >& details); + void setPresence (const std::string& accountID, const std::string& presence, const std::string& additionalInfo); + void setContactPresence (const std::string& accountID, const std::string& presence, const std::string& additionalInfo); }; diff --git a/sflphone-common/src/dbus/dbusmanager.h b/sflphone-common/src/dbus/dbusmanager.h index 47a36d304fd5d1f7af3b0493f301c36913708811..acd97c95fc267c9fce807bc0d438bf2d0be0b24e 100644 --- a/sflphone-common/src/dbus/dbusmanager.h +++ b/sflphone-common/src/dbus/dbusmanager.h @@ -1,17 +1,17 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com> - * + * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. diff --git a/sflphone-common/src/dbus/dbusmanagerimpl.h b/sflphone-common/src/dbus/dbusmanagerimpl.h index 916ae5a407aabd158bb5a92345a9e47a23313f0b..94a1cfc9d9908d4328bd10fa54ed3cc7c7e45e10 100644 --- a/sflphone-common/src/dbus/dbusmanagerimpl.h +++ b/sflphone-common/src/dbus/dbusmanagerimpl.h @@ -1,17 +1,17 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com> - * + * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -37,20 +37,25 @@ class ConfigurationManager; class CallManager; class NetworkManager; -class DBusManagerImpl { +class DBusManagerImpl +{ public: - CallManager * getCallManager(){ return _callManager; }; - ConfigurationManager * getConfigurationManager(){ return _configurationManager; }; + CallManager * getCallManager() { + return _callManager; + }; + ConfigurationManager * getConfigurationManager() { + return _configurationManager; + }; int exec(); void exit(); static const char* SERVER_NAME; - + private: CallManager* _callManager; ConfigurationManager* _configurationManager; Instance* _instanceManager; DBus::BusDispatcher _dispatcher; - NetworkManager* _networkManager; + NetworkManager* _networkManager; }; #endif diff --git a/sflphone-common/src/dbus/instance.h b/sflphone-common/src/dbus/instance.h index d963e5d1319860a7d137edba0c4081dc9dcc9eac..edccb09d9f662f6fb8040fc5eebb5fd03a053958 100644 --- a/sflphone-common/src/dbus/instance.h +++ b/sflphone-common/src/dbus/instance.h @@ -1,17 +1,17 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com> - * + * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -27,30 +27,34 @@ * shall include the source code for the parts of OpenSSL used as well * as that of the covered work. */ - + #ifndef INSTANCE_H #define INSTANCE_H +#pragma GCC diagnostic ignored "-Wignored-qualifiers" +#pragma GCC diagnostic ignored "-Wunused-parameter" #include "instance-glue.h" +#pragma GCC diagnostic warning "-Wignored-qualifiers" +#pragma GCC diagnostic warning "-Wunused-parameter" #include <dbus-c++/dbus.h> - + class Instance -: public org::sflphone::SFLphone::Instance_adaptor, - public DBus::IntrospectableAdaptor, - public DBus::ObjectAdaptor + : public org::sflphone::SFLphone::Instance_adaptor, + public DBus::IntrospectableAdaptor, + public DBus::ObjectAdaptor { -private: - int count; - -public: - Instance(DBus::Connection& connection); - static const char* SERVER_PATH; - - void Register( const int32_t& pid, const std::string& name ); - void Unregister( const int32_t& pid ); - int32_t getRegistrationCount( void ); - + private: + int count; + + public: + Instance (DBus::Connection& connection); + static const char* SERVER_PATH; + + void Register (const int32_t& pid, const std::string& name); + void Unregister (const int32_t& pid); + int32_t getRegistrationCount (void); + }; diff --git a/sflphone-common/src/dbus/networkmanager.h b/sflphone-common/src/dbus/networkmanager.h index 3754669751e101a6038130cb7d4d93c29b7219d7..78ee117f9324509a98d4c6e2e5360986ecaf8b8f 100644 --- a/sflphone-common/src/dbus/networkmanager.h +++ b/sflphone-common/src/dbus/networkmanager.h @@ -31,32 +31,35 @@ #ifndef NETWORKMANAGER_H #define NETWORKMANAGER_H +#pragma GCC diagnostic ignored "-Wignored-qualifiers" +#pragma GCC diagnostic ignored "-Wunused-parameter" #include "networkmanager_proxy.h" +#pragma GCC diagnostic warning "-Wignored-qualifiers" +#pragma GCC diagnostic warning "-Wunused-parameter" using namespace std; class NetworkManager -: public org::freedesktop::NetworkManager_proxy, - public DBus::IntrospectableProxy, - public DBus::ObjectProxy + : public org::freedesktop::NetworkManager_proxy, + public DBus::IntrospectableProxy, + public DBus::ObjectProxy { -public: - - NetworkManager(DBus::Connection&, const DBus::Path&, const char*); - void StateChanged(const uint32_t& state); - void PropertiesChanged(const std::map< std::string, ::DBus::Variant >& argin0); - string stateAsString(const uint32_t& state); - - enum NMState - { - NM_STATE_UNKNOWN = 0, - NM_STATE_ASLEEP, - NM_STATE_CONNECTING, - NM_STATE_CONNECTED, - NM_STATE_DISCONNECTED - }; - - static const string statesString[5]; + public: + + NetworkManager (DBus::Connection&, const DBus::Path&, const char*); + void StateChanged (const uint32_t& state); + void PropertiesChanged (const std::map< std::string, ::DBus::Variant >& argin0); + string stateAsString (const uint32_t& state); + + enum NMState { + NM_STATE_UNKNOWN = 0, + NM_STATE_ASLEEP, + NM_STATE_CONNECTING, + NM_STATE_CONNECTED, + NM_STATE_DISCONNECTED + }; + + static const string statesString[5]; }; #endif diff --git a/sflphone-common/src/dbus/networkmanager_proxy.h b/sflphone-common/src/dbus/networkmanager_proxy.h index 078925ceff22c9e0ebd0e21cf90868ab4b2da370..364b0e7bbb7952b24b5b7ab3505625387cfd3fb3 100644 --- a/sflphone-common/src/dbus/networkmanager_proxy.h +++ b/sflphone-common/src/dbus/networkmanager_proxy.h @@ -9,70 +9,69 @@ #include <dbus-c++/dbus.h> #include <cassert> -namespace org { -namespace freedesktop { +namespace org +{ +namespace freedesktop +{ class NetworkManager_proxy -: public ::DBus::InterfaceProxy + : public ::DBus::InterfaceProxy { -public: - - NetworkManager_proxy() - : ::DBus::InterfaceProxy("org.freedesktop.NetworkManager") - { - connect_signal(NetworkManager_proxy, StateChanged, _StateChanged_stub); - connect_signal(NetworkManager_proxy, PropertiesChanged, _PropertiesChanged_stub); - } - -public: - - /* properties exported by this interface */ -public: - - /* methods exported by this interface, - * this functions will invoke the corresponding methods on the remote objects - */ - std::vector< ::DBus::Path > GetDevices() - { - ::DBus::CallMessage call; - call.member("GetDevices"); - ::DBus::Message ret = invoke_method (call); - ::DBus::MessageIter ri = ret.reader(); - - std::vector< ::DBus::Path > argout; - ri >> argout; - return argout; - } - - -public: - - /* signal handlers for this interface - */ - virtual void StateChanged(const uint32_t& argin0) = 0; - virtual void PropertiesChanged(const std::map< std::string, ::DBus::Variant >& argin0) = 0; - -private: - - /* unmarshalers (to unpack the DBus message before calling the actual signal handler) - */ - void _StateChanged_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - uint32_t arg0; - ri >> arg0; - StateChanged(arg0); - } - void _PropertiesChanged_stub(const ::DBus::SignalMessage &sig) - { - ::DBus::MessageIter ri = sig.reader(); - - std::map< std::string, ::DBus::Variant > arg0; - ri >> arg0; - PropertiesChanged(arg0); - } + public: + + NetworkManager_proxy() + : ::DBus::InterfaceProxy ("org.freedesktop.NetworkManager") { + connect_signal (NetworkManager_proxy, StateChanged, _StateChanged_stub); + connect_signal (NetworkManager_proxy, PropertiesChanged, _PropertiesChanged_stub); + } + + public: + + /* properties exported by this interface */ + public: + + /* methods exported by this interface, + * this functions will invoke the corresponding methods on the remote objects + */ + std::vector< ::DBus::Path > GetDevices() { + ::DBus::CallMessage call; + call.member ("GetDevices"); + ::DBus::Message ret = invoke_method (call); + ::DBus::MessageIter ri = ret.reader(); + + std::vector< ::DBus::Path > argout; + ri >> argout; + return argout; + } + + + public: + + /* signal handlers for this interface + */ + virtual void StateChanged (const uint32_t& argin0) = 0; + virtual void PropertiesChanged (const std::map< std::string, ::DBus::Variant >& argin0) = 0; + + private: + + /* unmarshalers (to unpack the DBus message before calling the actual signal handler) + */ + void _StateChanged_stub (const ::DBus::SignalMessage &sig) { + ::DBus::MessageIter ri = sig.reader(); + + uint32_t arg0; + ri >> arg0; + StateChanged (arg0); + } + void _PropertiesChanged_stub (const ::DBus::SignalMessage &sig) { + ::DBus::MessageIter ri = sig.reader(); + + std::map< std::string, ::DBus::Variant > arg0; + ri >> arg0; + PropertiesChanged (arg0); + } }; -} } +} +} #endif //__dbusxx__networkmanager_proxy_h__PROXY_MARSHAL_H diff --git a/sflphone-common/src/eventthread.h b/sflphone-common/src/eventthread.h index eca20c22dc8c40ec39135eaf2539943f85373876..0285deec51f4af54641a5741746d87c7615294be 100644 --- a/sflphone-common/src/eventthread.h +++ b/sflphone-common/src/eventthread.h @@ -1,17 +1,17 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> - * + * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -42,34 +42,36 @@ class AlsaLayer; * @brief General thread to listen events continuously */ -class EventThread : public ost::Thread { +class EventThread : public ost::Thread +{ public: /** - * Thread constructor + * Thread constructor */ - EventThread (VoIPLink* link); - - ~EventThread (void){ + EventThread (VoIPLink* link); + + ~EventThread (void) { terminate(); } - + virtual void run () ; - + private: - EventThread(const EventThread& rh); // copy constructor - EventThread& operator=(const EventThread& rh); // assignment operator + EventThread (const EventThread& rh); // copy constructor + EventThread& operator= (const EventThread& rh); // assignment operator /** VoIPLink is the object being called by getEvents() method */ VoIPLink* _linkthread; }; -class AudioThread : public ost::Thread { +class AudioThread : public ost::Thread +{ public: AudioThread (AlsaLayer *alsa); - ~AudioThread (void){ + ~AudioThread (void) { terminate(); } @@ -77,7 +79,7 @@ class AudioThread : public ost::Thread { private: AudioThread (const AudioThread& at); - AudioThread& operator=(const AudioThread& at); + AudioThread& operator= (const AudioThread& at); AlsaLayer* _alsa; }; diff --git a/sflphone-common/src/global.h b/sflphone-common/src/global.h index 552616d7851be88197c105e84c062d3c0b2710fc..1ba1be17aaf644cafe0f6df786534840ac6d26d5 100644 --- a/sflphone-common/src/global.h +++ b/sflphone-common/src/global.h @@ -3,17 +3,17 @@ * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> * Author: Yan Morin <yan.morin@savoirfairelinux.com> * Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com> - * + * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -71,7 +71,7 @@ static const SOUND_FORMAT INT32 = 0x8; #define SUCCESS 0 #define ASSERT( expected , value) if( value == expected ) return SUCCESS; \ - else return 1; + else return 1; #define PIDFILE "sfl.pid" #ifdef DATAFORMAT_IS_FLOAT @@ -89,23 +89,23 @@ static const SOUND_FORMAT INT32 = 0x8; #define RINGDIR "ringtones" /** Ringtones directory */ #define CODECDIR "codecs" /** Codecs directory */ -#define SIZEBUF 1024*1024 +#define SIZEBUF 100000 /** About 12 sec of buffering at 8000 Hz*/ #define STATIC_BUFSIZE 5000 #define ALSA_DFT_CARD_ID 0 /** Index of the default soundcard */ -#define PCM_PLUGHW "plughw" /** Alsa plugin */ +#define PCM_PLUGHW "plughw" /** Alsa plugin */ #define PCM_DEFAULT "default" /** Default ALSA plugin */ #define PCM_DMIX "plug:dmix" /** Alsa plugin for software mixing */ #define PCM_DSNOOP "plug:dsnoop" /** Alsa plugin for microphone sharing */ #define PCM_DMIX_DSNOOP "dmix/dsnoop" /** Audio profile using Alsa dmix/dsnoop */ -#define SFL_CODEC_VALID_PREFIX "libcodec_" /** Valid prefix for codecs shared library */ +#define SFL_CODEC_VALID_PREFIX "libcodec_" /** Valid prefix for codecs shared library */ #define SFL_CODEC_VALID_EXTEN ".so" /** Valid extension for codecs shared library */ #define CURRENT_DIR "." /** Current directory */ #define PARENT_DIR ".." /** Parent directory */ -#define SFL_PCM_BOTH 0x0021 /** To open both playback and capture devices */ +#define SFL_PCM_BOTH 0x0021 /** To open both playback and capture devices */ #define SFL_PCM_PLAYBACK 0x0022 /** To open playback device only */ #define SFL_PCM_CAPTURE 0x0023 /** To open capture device only */ #define SFL_PCM_RINGTONE 0x0024 @@ -133,11 +133,11 @@ static const SOUND_FORMAT INT32 = 0x8; #define NETWORK_UNREACHABLE 0x0011 /** Network unreachable */ #define PULSEAUDIO_NOT_RUNNING 0x0100 /** Pulseaudio is not running */ -#define ALSA 0 +#define ALSA 0 #define PULSEAUDIO 1 -#define CHECK_INTERFACE( layer , api ) (layer == api) +#define CHECK_INTERFACE( layer , api ) (layer == api) -#define UNUSED __attribute__((__unused__)) +#define UNUSED __attribute__((__unused__)) #define DEFAULT_SIP_PORT "5060" #define DEFAULT_SIP_TLS_PORT "5061" @@ -147,27 +147,27 @@ static const SOUND_FORMAT INT32 = 0x8; /** Enumeration that contains known audio payloads */ typedef enum { - // http://www.iana.org/assignments/rtp-parameters - // http://www.gnu.org/software/ccrtp/doc/refman/html/formats_8h.html#a0 - // 0 PCMU A 8000 1 [RFC3551] - PAYLOAD_CODEC_ULAW = 0, - // 3 GSM A 8000 1 [RFC3551] - PAYLOAD_CODEC_GSM = 3, - // 8 PCMA A 8000 1 [RFC3551] - PAYLOAD_CODEC_ALAW = 8, - // 9 G722 A 8000 1 [RFC3551] - PAYLOAD_CODEC_G722 = 9, - // http://www.ietf.org/rfc/rfc3952.txt - // 97 iLBC/8000 - PAYLOAD_CODEC_ILBC_20 = 97, - PAYLOAD_CODEC_ILBC_30 = 98, - // http://www.speex.org/drafts/draft-herlein-speex-rtp-profile-00.txt - // 97 speex/8000 - // http://support.xten.com/viewtopic.php?p=8684&sid=3367a83d01fdcad16c7459a79859b08e - // 100 speex/16000 - PAYLOAD_CODEC_SPEEX_8000 = 110, - PAYLOAD_CODEC_SPEEX_16000 = 111, - PAYLOAD_CODEC_SPEEX_32000 = 112 + // http://www.iana.org/assignments/rtp-parameters + // http://www.gnu.org/software/ccrtp/doc/refman/html/formats_8h.html#a0 + // 0 PCMU A 8000 1 [RFC3551] + PAYLOAD_CODEC_ULAW = 0, + // 3 GSM A 8000 1 [RFC3551] + PAYLOAD_CODEC_GSM = 3, + // 8 PCMA A 8000 1 [RFC3551] + PAYLOAD_CODEC_ALAW = 8, + // 9 G722 A 8000 1 [RFC3551] + PAYLOAD_CODEC_G722 = 9, + // http://www.ietf.org/rfc/rfc3952.txt + // 97 iLBC/8000 + PAYLOAD_CODEC_ILBC_20 = 97, + PAYLOAD_CODEC_ILBC_30 = 98, + // http://www.speex.org/drafts/draft-herlein-speex-rtp-profile-00.txt + // 97 speex/8000 + // http://support.xten.com/viewtopic.php?p=8684&sid=3367a83d01fdcad16c7459a79859b08e + // 100 speex/16000 + PAYLOAD_CODEC_SPEEX_8000 = 110, + PAYLOAD_CODEC_SPEEX_16000 = 111, + PAYLOAD_CODEC_SPEEX_32000 = 112 } AudioCodecType; /** The struct to reflect the order the user wants to use the codecs */ diff --git a/sflphone-common/src/history/historyitem.h b/sflphone-common/src/history/historyitem.h index 55b12cb5b8785516cbb77f46b43570018a037ff2..52721d8522939a1fd0514893a565b17eb0e20626 100644 --- a/sflphone-common/src/history/historyitem.h +++ b/sflphone-common/src/history/historyitem.h @@ -40,10 +40,11 @@ typedef enum CallType { CALL_MISSED, CALL_INCOMING, CALL_OUTGOING -}CallType; +} CallType; -class HistoryItem { +class HistoryItem +{ public: /* @@ -55,7 +56,7 @@ class HistoryItem { * Constructor from a serialized form */ HistoryItem (std::string, std::string=""); - + /* * Destructor */ @@ -82,7 +83,7 @@ class HistoryItem { std::string _timestamp_start; std::string _timestamp_stop; - /* + /* * Represents the type of call * Has be either CALL_MISSED, CALL_INCOMING or CALL_OUTGOING */ @@ -96,7 +97,7 @@ class HistoryItem { /* * The account the call was made with - */ + */ std::string _account_id; }; diff --git a/sflphone-common/src/history/historymanager.cpp b/sflphone-common/src/history/historymanager.cpp index 909f20fd06945ed9a1f0a6022280df1569667493..57a70f8459fa76f51b13c10a89f5419bdd86b23d 100644 --- a/sflphone-common/src/history/historymanager.cpp +++ b/sflphone-common/src/history/historymanager.cpp @@ -77,12 +77,14 @@ bool HistoryManager::save_history (void) bool HistoryManager::load_history_from_file (Conf::ConfigTree *history_list) { - bool exist; + int exist; - exist = history_list->populateFromFile (_history_path); + _debug ("HistoryManager: Load history from file %s", _history_path.c_str()); + + exist = history_list->populateFromFile (_history_path.c_str()); _history_loaded = (exist == 2) ? false : true; - return exist; + return _history_loaded; } int HistoryManager::load_history_items_map (Conf::ConfigTree *history_list, int limit) @@ -97,6 +99,8 @@ int HistoryManager::load_history_items_map (Conf::ConfigTree *history_list, int int history_limit; time_t current_timestamp; + _debug ("HistoryManager: Load history items"); + // We want to save only the items recent enough (ie compared to CONFIG_HISTORY_LIMIT) // Get the current timestamp (void) time (¤t_timestamp); diff --git a/sflphone-common/src/history/historymanager.h b/sflphone-common/src/history/historymanager.h index e8966dfeb200e832dd3819df842843925155a879..2796315aeaaf641ae24be164afa2546a8ea3c260 100644 --- a/sflphone-common/src/history/historymanager.h +++ b/sflphone-common/src/history/historymanager.h @@ -32,15 +32,16 @@ #ifndef _HISTORY_MANAGER #define _HISTORY_MANAGER -#include "historyitem.h" +#include "historyitem.h" #include <global.h> #include <user_cfg.h> #define DAY_UNIX_TIMESTAMP 86400 // Number of seconds in one day: 60 x 60 x 24 -typedef std::map <std::string, HistoryItem*> HistoryItemMap; +typedef std::map <std::string, HistoryItem*> HistoryItemMap; -class HistoryManager { +class HistoryManager +{ public: /* @@ -95,7 +96,7 @@ class HistoryManager { inline void set_history_path (std::string filename) { _history_path = filename; } - + /* *@return int The number of items found in the history file */ @@ -108,13 +109,12 @@ class HistoryManager { int set_serialized_history (std::map <std::string, std::string> history, int limit); private: - inline int get_unix_timestamp_equivalent (int days) - { + inline int get_unix_timestamp_equivalent (int days) { return days * DAY_UNIX_TIMESTAMP; } - - int getConfigInt(const std::string& section, const std::string& name, Conf::ConfigTree *history_list); - std::string getConfigString(const std::string& section, const std::string& name, Conf::ConfigTree *history_list); + + int getConfigInt (const std::string& section, const std::string& name, Conf::ConfigTree *history_list); + std::string getConfigString (const std::string& section, const std::string& name, Conf::ConfigTree *history_list); /* * Set the path to the history file @@ -139,7 +139,7 @@ class HistoryManager { /* * The path to the history file - */ + */ std::string _history_path; diff --git a/sflphone-common/src/hooks/urlhook.h b/sflphone-common/src/hooks/urlhook.h index 49208656063665caf781c681d8247c368e9e5e3b..90a463771f7edd8d499440c63835b6a087130401 100644 --- a/sflphone-common/src/hooks/urlhook.h +++ b/sflphone-common/src/hooks/urlhook.h @@ -36,7 +36,8 @@ #define RUN_COMMAND(command) system(command); -class UrlHook { +class UrlHook +{ public: /** diff --git a/sflphone-common/src/iax/iaxaccount.cpp b/sflphone-common/src/iax/iaxaccount.cpp index 2c277cb0827ee138efb7e835d4362a188ba7d032..ee4428aaba68048e3c13a84ae27482974c069f3c 100644 --- a/sflphone-common/src/iax/iaxaccount.cpp +++ b/sflphone-common/src/iax/iaxaccount.cpp @@ -47,6 +47,195 @@ IAXAccount::~IAXAccount() _link = NULL; } +void IAXAccount::serialize (Conf::YamlEmitter *emitter) +{ + _debug ("IaxAccount: serialize %s", _accountID.c_str()); + + Conf::MappingNode accountmap (NULL); + + Conf::ScalarNode id (Account::_accountID); + Conf::ScalarNode username (Account::_username); + Conf::ScalarNode password (Account::_password); + Conf::ScalarNode alias (Account::_alias); + Conf::ScalarNode hostname (Account::_hostname); + Conf::ScalarNode enable (_enabled ? "true" : "false"); + Conf::ScalarNode type (Account::_type); + Conf::ScalarNode mailbox ("97"); + + Conf::ScalarNode codecs (_codecStr); + Conf::ScalarNode displayName (_displayName); + + accountmap.setKeyValue (aliasKey, &alias); + accountmap.setKeyValue (typeKey, &type); + accountmap.setKeyValue (idKey, &id); + accountmap.setKeyValue (usernameKey, &username); + accountmap.setKeyValue (passwordKey, &password); + accountmap.setKeyValue (hostnameKey, &hostname); + accountmap.setKeyValue (accountEnableKey, &enable); + accountmap.setKeyValue (mailboxKey, &mailbox); + + accountmap.setKeyValue (displayNameKey, &displayName); + accountmap.setKeyValue (codecsKey, &codecs); + + try { + emitter->serializeAccount (&accountmap); + } catch (Conf::YamlEmitterException &e) { + _error ("ConfigTree: %s", e.what()); + } +} + +void IAXAccount::unserialize (Conf::MappingNode *map) +{ + Conf::ScalarNode *val; + + _debug ("IaxAccount: Unserialize"); + + val = (Conf::ScalarNode *) (map->getValue (aliasKey)); + + if (val) { + _alias = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (typeKey)); + + if (val) { + _type = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (idKey)); + + if (val) { + _accountID = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (usernameKey)); + + if (val) { + _username = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (passwordKey)); + + if (val) { + _password = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (hostnameKey)); + + if (val) { + _hostname = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (accountEnableKey)); + + if (val) { + _enabled = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + // val = (Conf::ScalarNode *)(map->getValue(mailboxKey)); + + val = (Conf::ScalarNode *) (map->getValue (codecsKey)); + + if (val) { + _codecStr = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (displayNameKey)); + + if (val) { + _displayName = val->getValue(); + val = NULL; + } + +} + +void IAXAccount::setAccountDetails (const std::map<std::string, std::string>& details) +{ + std::map<std::string, std::string> map_cpy; + std::map<std::string, std::string>::iterator iter; + + _debug ("IaxAccount: Set account details: %s", _accountID.c_str()); + + // Work on a copy + map_cpy = details; + + std::string alias; + std::string type; + std::string hostname; + std::string username; + std::string password; + std::string mailbox; + std::string accountEnable; + + std::string ua_name; + + // Account setting common to SIP and IAX + find_in_map (CONFIG_ACCOUNT_ALIAS, alias) + find_in_map (CONFIG_ACCOUNT_TYPE, type) + find_in_map (HOSTNAME, hostname) + find_in_map (USERNAME, username) + find_in_map (PASSWORD, password) + find_in_map (CONFIG_ACCOUNT_MAILBOX, mailbox); + find_in_map (CONFIG_ACCOUNT_ENABLE, accountEnable); + + setAlias (alias); + setType (type); + setUsername (username); + setHostname (hostname); + setPassword (password); + setEnabled ( (accountEnable.compare ("true") == 0) ? true : false); + + std::string displayName; + find_in_map (DISPLAY_NAME, displayName) + setDisplayName (displayName); + + find_in_map (USERAGENT, ua_name) + setUseragent (ua_name); + +} + +std::map<std::string, std::string> IAXAccount::getAccountDetails() +{ + std::map<std::string, std::string> a; + + _debug ("IaxAccount: get account details %s", _accountID.c_str()); + + a.insert (std::pair<std::string, std::string> (ACCOUNT_ID, _accountID)); + a.insert (std::pair<std::string, std::string> (CONFIG_ACCOUNT_ALIAS, getAlias())); + a.insert (std::pair<std::string, std::string> (CONFIG_ACCOUNT_ENABLE, isEnabled() ? "true" : "false")); + a.insert (std::pair<std::string, std::string> (CONFIG_ACCOUNT_TYPE, getType())); + a.insert (std::pair<std::string, std::string> (HOSTNAME, getHostname())); + a.insert (std::pair<std::string, std::string> (USERNAME, getUsername())); + a.insert (std::pair<std::string, std::string> (PASSWORD, getPassword())); + + RegistrationState state = Unregistered; + std::string registrationStateCode; + std::string registrationStateDescription; + + state = getRegistrationState(); + int code = getRegistrationStateDetailed().first; + std::stringstream out; + out << code; + registrationStateCode = out.str(); + registrationStateDescription = getRegistrationStateDetailed().second; + + a.insert (std::pair<std::string, std::string> (REGISTRATION_STATUS, Manager::instance().mapStateNumberToString (state))); + a.insert (std::pair<std::string, std::string> (REGISTRATION_STATE_CODE, registrationStateCode)); + a.insert (std::pair<std::string, std::string> (REGISTRATION_STATE_DESCRIPTION, registrationStateDescription)); + a.insert (std::pair<std::string, std::string> (USERAGENT, getUseragent())); + + return a; +} + + void IAXAccount::setVoIPLink() { @@ -57,9 +246,9 @@ int IAXAccount::registerVoIPLink() _link->init(); // Stuff needed for IAX registration - setHostname (Manager::instance().getConfigString (_accountID, HOSTNAME)); - setUsername (Manager::instance().getConfigString (_accountID, USERNAME)); - setPassword (Manager::instance().getConfigString (_accountID, PASSWORD)); + setHostname (_hostname); + setUsername (_username); + setPassword (_password); _link->sendRegister (_accountID); diff --git a/sflphone-common/src/iax/iaxaccount.h b/sflphone-common/src/iax/iaxaccount.h index 929f7af38a8fa391bc154c88fa05f72ce138cbec..d9596abb9b60d548d5fd32f8cb5bce5e2c6d4e90 100644 --- a/sflphone-common/src/iax/iaxaccount.h +++ b/sflphone-common/src/iax/iaxaccount.h @@ -2,17 +2,17 @@ * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. * Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com> * Author: Yan Morin <yan.morin@savoirfairelinux.com> - * + * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -40,14 +40,22 @@ class IAXAccount : public Account { public: - IAXAccount(const AccountID& accountID); + IAXAccount (const AccountID& accountID); ~IAXAccount(); - void setVoIPLink (); + virtual void serialize (Conf::YamlEmitter *emitter); + + virtual void unserialize (Conf::MappingNode *map); - /** - * Actually useless, since config loading is done in init() + void setAccountDetails (const std::map<std::string, std::string>& details); + + std::map<std::string, std::string> getAccountDetails(); + + void setVoIPLink (); + + /** + * Actually useless, since config loading is done in init() */ void loadConfig(); diff --git a/sflphone-common/src/iax/iaxcall.h b/sflphone-common/src/iax/iaxcall.h index 7ecb1558cacf79ab3e79f6c56276726fd4d24503..fae514039eefac9d4b3f33017ad2a6f48871eddd 100644 --- a/sflphone-common/src/iax/iaxcall.h +++ b/sflphone-common/src/iax/iaxcall.h @@ -39,110 +39,120 @@ /** * @file: iaxcall.h - * @brief IAXCall are IAX implementation of a normal Call + * @brief IAXCall are IAX implementation of a normal Call */ class IAXCall : public Call { -public: - /** - * Constructor - * @param id The unique ID of the call - * @param type The type of the call - */ - IAXCall(const CallID& id, Call::CallType type); - - /** - * Destructor - */ - ~IAXCall(); - - /** - * @return iax_session* The session pointer or NULL - */ - struct iax_session* getSession() { return _session; } - - /** - * Set the session pointer - * @param session the session pointer to assign - */ - void setSession(struct iax_session* session) { _session = session; } - - /** - * Set format (one single bit) - * This function sets the _audioCodec variable with the correct - * codec. - * @param format The format representing the codec - */ - void setFormat(int format); - - /** - * Get format for the voice codec used - * @return int Bitmask for codecs defined in iax/frame.h - */ - int getFormat() { return _format; } - - - /** - * @return int The bitwise list of supported formats - */ - int getSupportedFormat (std::string accountID); - - /** - * Return a format (int) with the first matching codec selected. - * - * This considers the order of the appearance in the CodecMap, - * thus, the order of preference. - * - * NOTE: Everything returned is bound to the content of the local - * CodecMap, so it won't return format values that aren't valid - * in this call context. - * - * @param needles The format(s) (bitwise) you are looking for to match - * @return int The matching format, thus 0 if none matches - */ - int getFirstMatchingFormat(int needles, std::string accountID); - - // AUDIO - /** - * Set internal codec Map: initialization only, not protected - * @param map The codec map - */ - void setCodecMap(const CodecDescriptor& map) { _codecMap = map; } - - /** - * Get internal codec Map: initialization only, not protected - * @return CodecDescriptor The codec map - */ - CodecDescriptor& getCodecMap(); - - /** - * Return audio codec [mutex protected] - * @return AudioCodecType The payload of the codec - */ - AudioCodecType getAudioCodec(); - -private: - /** Each call is associated with an iax_session */ - struct iax_session* _session; - - /** - * Set the audio codec used. [not protected] - * @param audioCodec The payload of the codec - */ - void setAudioCodec(AudioCodecType audioCodec) { _audioCodec = audioCodec; } - - /** Codec Map */ - CodecDescriptor _codecMap; - - /** Codec pointer */ - AudioCodecType _audioCodec; - - /** - * Format currently in use in the conversation, - * sent in each outgoing voice packet. - */ - int _format; + public: + /** + * Constructor + * @param id The unique ID of the call + * @param type The type of the call + */ + IAXCall (const CallID& id, Call::CallType type); + + /** + * Destructor + */ + ~IAXCall(); + + /** + * @return iax_session* The session pointer or NULL + */ + struct iax_session* getSession() { + return _session; + } + + /** + * Set the session pointer + * @param session the session pointer to assign + */ + void setSession (struct iax_session* session) { + _session = session; + } + + /** + * Set format (one single bit) + * This function sets the _audioCodec variable with the correct + * codec. + * @param format The format representing the codec + */ + void setFormat (int format); + + /** + * Get format for the voice codec used + * @return int Bitmask for codecs defined in iax/frame.h + */ + int getFormat() { + return _format; + } + + + /** + * @return int The bitwise list of supported formats + */ + int getSupportedFormat (std::string accountID); + + /** + * Return a format (int) with the first matching codec selected. + * + * This considers the order of the appearance in the CodecMap, + * thus, the order of preference. + * + * NOTE: Everything returned is bound to the content of the local + * CodecMap, so it won't return format values that aren't valid + * in this call context. + * + * @param needles The format(s) (bitwise) you are looking for to match + * @return int The matching format, thus 0 if none matches + */ + int getFirstMatchingFormat (int needles, std::string accountID); + + // AUDIO + /** + * Set internal codec Map: initialization only, not protected + * @param map The codec map + */ + void setCodecMap (const CodecDescriptor& map) { + _codecMap = map; + } + + /** + * Get internal codec Map: initialization only, not protected + * @return CodecDescriptor The codec map + */ + CodecDescriptor& getCodecMap(); + + /** + * Return audio codec [mutex protected] + * @return AudioCodecType The payload of the codec + */ + AudioCodecType getAudioCodec(); + + private: + /** Each call is associated with an iax_session */ + struct iax_session* _session; + + /** + * Set the audio codec used. [not protected] + * @param audioCodec The payload of the codec + */ + void setAudioCodec (AudioCodecType audioCodec) { + _audioCodec = audioCodec; + } + + /** Codec Map */ + CodecDescriptor _codecMap; + + /** Codec pointer */ + AudioCodecType _audioCodec; + + /** + * Format currently in use in the conversation, + * sent in each outgoing voice packet. + */ + int _format; }; #endif diff --git a/sflphone-common/src/iax/iaxvoiplink.cpp b/sflphone-common/src/iax/iaxvoiplink.cpp index 0649b34df34770174505e3618ddab47c0512aad1..a9d4f117ea361c1fdba5731c715dcc57b9b2c77e 100644 --- a/sflphone-common/src/iax/iaxvoiplink.cpp +++ b/sflphone-common/src/iax/iaxvoiplink.cpp @@ -408,19 +408,23 @@ IAXVoIPLink::getIAXCall (const CallID& id) int -IAXVoIPLink::sendRegister (AccountID id) +IAXVoIPLink::sendRegister (AccountID id UNUSED) { IAXAccount *account; bool result; + _debug ("IAX: Sending registration"); + result = false; account = dynamic_cast<IAXAccount *> (getAccountPtr()); if (account->getHostname().empty()) { + _error ("IAX: Error: Account hostname is empty"); return false; } if (account->getUsername().empty()) { + _error ("IAX: Error: Account username is empty"); return false; } @@ -435,11 +439,11 @@ IAXVoIPLink::sendRegister (AccountID id) _regSession = iax_session_new(); if (!_regSession) { - _debug ("Error when generating new session for register"); + _debug ("IAX: Error when generating new session for register"); } else { - _debug ("IAX Sending registration to %s with user %s", account->getHostname().c_str() , account->getUsername().c_str()); + _debug ("IAX: Sending registration to %s with user %s", account->getHostname().c_str() , account->getUsername().c_str()); int val = iax_register (_regSession, account->getHostname().data(), account->getUsername().data(), account->getPassword().data(), 120); - _debug ("Return value: %d", val); + _debug ("IAX: Return value: %d", val); // set the time-out to 15 seconds, after that, resend a registration request. // until we unregister. _nextRefreshStamp = time (NULL) + 10; @@ -455,7 +459,7 @@ IAXVoIPLink::sendRegister (AccountID id) } int -IAXVoIPLink::sendUnregister (AccountID id) +IAXVoIPLink::sendUnregister (AccountID id UNUSED) { IAXAccount *account; diff --git a/sflphone-common/src/iax/iaxvoiplink.h b/sflphone-common/src/iax/iaxvoiplink.h index 0f61f5958823b218193d838a2c89df133654805b..4fe101b4d07029b51947dd8cda6c9273fbaf3e5c 100644 --- a/sflphone-common/src/iax/iaxvoiplink.h +++ b/sflphone-common/src/iax/iaxvoiplink.h @@ -3,17 +3,17 @@ * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> * Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com> * Author: Yan Morin <yan.morin@savoirfairelinux.com> - * + * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -48,270 +48,276 @@ class AudioLayer; /** * @file iaxvoiplink.h - * @brief VoIPLink contains a thread that listen to external events + * @brief VoIPLink contains a thread that listen to external events * and contains IAX Call related functions */ class IAXVoIPLink : public VoIPLink { - public: - - /** - * Constructor - * @param accountID The account containing the voip link - */ - IAXVoIPLink(const AccountID& accountID); - - /** - * Destructor - */ - ~IAXVoIPLink(); - - /** - * Listen to events sent by the call manager ( asterisk, etc .. ) - */ - void getEvent(void); - - /** - * Init the voip link - * @return true if successful - * false otherwise - */ - bool init (void); - - /** - * Terminate a voip link by clearing the call list - */ - void terminate (void); - - /** - * Terminate on call - */ - void terminateOneCall(const CallID& id); - - /** - * Send out registration - * @return bool The new registration state (are we registered ?) - */ - int sendRegister (AccountID id); - - /** - * Destroy registration session - * @todo Send an IAX_COMMAND_REGREL to force unregistration upstream. - * Urgency: low - * @return bool true if we're registered upstream - * false otherwise - */ - int sendUnregister (AccountID id); - - /** - * Create a new outgoing call - * @param id The ID of the call - * @param toUrl The address to call - * @return Call* A pointer on the call - */ - Call* newOutgoingCall(const CallID& id, const std::string& toUrl); - - /** - * Answer a call - * @param id The ID of the call - * @return bool true on success - * false otherwise - */ - bool answer(const CallID& id); - - /** - * Hangup a call - * @param id The ID of the call - * @return bool true on success - * false otherwise - */ - bool hangup(const CallID& id); - - /** - * Peer Hungup a call - * @param id The ID of the call - * @return bool true on success - * false otherwise - */ - bool peerHungup(const CallID& id); - - /** - * Cancel a call - * @param id The ID of the call - * @return bool true on success - * false otherwise - */ - bool cancel(const CallID& id UNUSED ) { return false; } - - /** - * Put a call on hold - * @param id The ID of the call - * @return bool true on success - * false otherwise - */ - bool onhold(const CallID& id); - - /** - * Put a call off hold - * @param id The ID of the call - * @return bool true on success - * false otherwise - */ - bool offhold(const CallID& id); - - /** - * Transfer a call - * @param id The ID of the call - * @param to The recipient of the transfer - * @return bool true on success - * false otherwise - */ - bool transfer(const CallID& id, const std::string& to); - - /** - * Refuse a call - * @param id The ID of the call - * @return bool true on success - * false otherwise - */ - bool refuse (const CallID& id); - - /** - * Send DTMF - * @param id The ID of the call - * @param code The code of the DTMF - * @return bool true on success - * false otherwise - */ - bool carryingDTMFdigits(const CallID& id, char code); - - bool sendMessage(const std::string& to UNUSED, const std::string& body UNUSED) { return false; } - - bool isContactPresenceSupported() { return false; } - - /** - * Return the codec protocol used for this call - * @param id The call identifier - */ - std::string getCurrentCodecName(); - - - public: // iaxvoiplink only - - void updateAudiolayer( void ); - - private: - - /* - * Decode the message count IAX send. - * Returns only the new messages number - * - * @param msgcount The value sent by IAX in the REGACK message - * @return int The number of new messages waiting for the current registered user - */ - int processIAXMsgCount( int msgcount ); - - - /** - * Get IAX Call from an id - * @param id CallId - *Â @return IAXCall pointer or 0 - */ - IAXCall* getIAXCall(const CallID& id); - - /** - * Delete every call - */ - void terminateIAXCall(); - - /** - * Find a iaxcall by iax session number - * @param session an iax_session valid pointer - * @return iaxcall or 0 if not found - */ - IAXCall* iaxFindCallBySession(struct iax_session* session); - - /** - * Handle IAX Event for a call - * @param event An iax_event pointer - * @param call An IAXCall pointer - */ - void iaxHandleCallEvent(iax_event* event, IAXCall* call); - - /** - * Handle the VOICE events specifically - * @param event The iax_event containing the IAX_EVENT_VOICE - * @param call The associated IAXCall - */ - void iaxHandleVoiceEvent(iax_event* event, IAXCall* call); - - /** - * Handle IAX Registration Reply event - * @param event An iax_event pointer - */ - void iaxHandleRegReply(iax_event* event); - - /** - * Handle IAX pre-call setup-related events - * @param event An iax_event pointer - */ - void iaxHandlePrecallEvent(iax_event* event); - - /** - * Work out the audio data from Microphone to IAX2 channel - */ - void sendAudioFromMic(void); - - /** - * Send an outgoing call invite to iax - * @param call An IAXCall pointer - */ - bool iaxOutgoingInvite(IAXCall* call); - - /** Threading object */ - EventThread* _evThread; - - /** registration session : 0 if not register */ - struct iax_session* _regSession; - - /** Timestamp of when we should refresh the registration up with - * the registrar. Values can be: EPOCH timestamp, 0 if we want no registration, 1 - * to force a registration. */ - int _nextRefreshStamp; - - /** Mutex for iax_ calls, since we're the only one dealing with the incorporated - * iax_stuff inside this class. */ - ost::Mutex _mutexIAX; - - /** Connection to audio card/device */ - AudioLayer* audiolayer; - - /** Mic-data related buffers */ - SFLDataFormat* micData; - SFLDataFormat* micDataConverted; - unsigned char* micDataEncoded; - - /** Speaker-data related buffers */ - SFLDataFormat* spkrDataDecoded; - SFLDataFormat* spkrDataConverted; - - /** Sample rate converter object */ - SamplerateConverter* converter; - - int converterSamplingRate; - - /** number of sample */ - int nbSample_; - - /** number of sample before conversion (recording) */ - int nbSampleForRec_; - - /* URL hook */ - UrlHook *urlhook; - - /** Counter for IncomingCallNotification */ - int countTime; + public: + + /** + * Constructor + * @param accountID The account containing the voip link + */ + IAXVoIPLink (const AccountID& accountID); + + /** + * Destructor + */ + ~IAXVoIPLink(); + + /** + * Listen to events sent by the call manager ( asterisk, etc .. ) + */ + void getEvent (void); + + /** + * Init the voip link + * @return true if successful + * false otherwise + */ + bool init (void); + + /** + * Terminate a voip link by clearing the call list + */ + void terminate (void); + + /** + * Terminate on call + */ + void terminateOneCall (const CallID& id); + + /** + * Send out registration + * @return bool The new registration state (are we registered ?) + */ + int sendRegister (AccountID id); + + /** + * Destroy registration session + * @todo Send an IAX_COMMAND_REGREL to force unregistration upstream. + * Urgency: low + * @return bool true if we're registered upstream + * false otherwise + */ + int sendUnregister (AccountID id); + + /** + * Create a new outgoing call + * @param id The ID of the call + * @param toUrl The address to call + * @return Call* A pointer on the call + */ + Call* newOutgoingCall (const CallID& id, const std::string& toUrl); + + /** + * Answer a call + * @param id The ID of the call + * @return bool true on success + * false otherwise + */ + bool answer (const CallID& id); + + /** + * Hangup a call + * @param id The ID of the call + * @return bool true on success + * false otherwise + */ + bool hangup (const CallID& id); + + /** + * Peer Hungup a call + * @param id The ID of the call + * @return bool true on success + * false otherwise + */ + bool peerHungup (const CallID& id); + + /** + * Cancel a call + * @param id The ID of the call + * @return bool true on success + * false otherwise + */ + bool cancel (const CallID& id UNUSED) { + return false; + } + + /** + * Put a call on hold + * @param id The ID of the call + * @return bool true on success + * false otherwise + */ + bool onhold (const CallID& id); + + /** + * Put a call off hold + * @param id The ID of the call + * @return bool true on success + * false otherwise + */ + bool offhold (const CallID& id); + + /** + * Transfer a call + * @param id The ID of the call + * @param to The recipient of the transfer + * @return bool true on success + * false otherwise + */ + bool transfer (const CallID& id, const std::string& to); + + /** + * Refuse a call + * @param id The ID of the call + * @return bool true on success + * false otherwise + */ + bool refuse (const CallID& id); + + /** + * Send DTMF + * @param id The ID of the call + * @param code The code of the DTMF + * @return bool true on success + * false otherwise + */ + bool carryingDTMFdigits (const CallID& id, char code); + + bool sendMessage (const std::string& to UNUSED, const std::string& body UNUSED) { + return false; + } + + bool isContactPresenceSupported() { + return false; + } + + /** + * Return the codec protocol used for this call + * @param id The call identifier + */ + std::string getCurrentCodecName(); + + + public: // iaxvoiplink only + + void updateAudiolayer (void); + + private: + + /* + * Decode the message count IAX send. + * Returns only the new messages number + * + * @param msgcount The value sent by IAX in the REGACK message + * @return int The number of new messages waiting for the current registered user + */ + int processIAXMsgCount (int msgcount); + + + /** + * Get IAX Call from an id + * @param id CallId + *Â @return IAXCall pointer or 0 + */ + IAXCall* getIAXCall (const CallID& id); + + /** + * Delete every call + */ + void terminateIAXCall(); + + /** + * Find a iaxcall by iax session number + * @param session an iax_session valid pointer + * @return iaxcall or 0 if not found + */ + IAXCall* iaxFindCallBySession (struct iax_session* session); + + /** + * Handle IAX Event for a call + * @param event An iax_event pointer + * @param call An IAXCall pointer + */ + void iaxHandleCallEvent (iax_event* event, IAXCall* call); + + /** + * Handle the VOICE events specifically + * @param event The iax_event containing the IAX_EVENT_VOICE + * @param call The associated IAXCall + */ + void iaxHandleVoiceEvent (iax_event* event, IAXCall* call); + + /** + * Handle IAX Registration Reply event + * @param event An iax_event pointer + */ + void iaxHandleRegReply (iax_event* event); + + /** + * Handle IAX pre-call setup-related events + * @param event An iax_event pointer + */ + void iaxHandlePrecallEvent (iax_event* event); + + /** + * Work out the audio data from Microphone to IAX2 channel + */ + void sendAudioFromMic (void); + + /** + * Send an outgoing call invite to iax + * @param call An IAXCall pointer + */ + bool iaxOutgoingInvite (IAXCall* call); + + /** Threading object */ + EventThread* _evThread; + + /** registration session : 0 if not register */ + struct iax_session* _regSession; + + /** Timestamp of when we should refresh the registration up with + * the registrar. Values can be: EPOCH timestamp, 0 if we want no registration, 1 + * to force a registration. */ + int _nextRefreshStamp; + + /** Mutex for iax_ calls, since we're the only one dealing with the incorporated + * iax_stuff inside this class. */ + ost::Mutex _mutexIAX; + + /** Connection to audio card/device */ + AudioLayer* audiolayer; + + /** Mic-data related buffers */ + SFLDataFormat* micData; + SFLDataFormat* micDataConverted; + unsigned char* micDataEncoded; + + /** Speaker-data related buffers */ + SFLDataFormat* spkrDataDecoded; + SFLDataFormat* spkrDataConverted; + + /** Sample rate converter object */ + SamplerateConverter* converter; + + int converterSamplingRate; + + /** number of sample */ + int nbSample_; + + /** number of sample before conversion (recording) */ + int nbSampleForRec_; + + /* URL hook */ + UrlHook *urlhook; + + /** Counter for IncomingCallNotification */ + int countTime; }; #endif diff --git a/sflphone-common/src/logger.h b/sflphone-common/src/logger.h index 7bf8ec75d60e7a0607d6abfbeeda9a17921f92ad..58c15c4d94cbd9ac8256fd47cf446fc906c75696 100644 --- a/sflphone-common/src/logger.h +++ b/sflphone-common/src/logger.h @@ -35,10 +35,10 @@ namespace Logger { - void log(const int, const char*, ...); +void log (const int, const char*, ...); - void setConsoleLog(bool); - void setDebugMode(bool); +void setConsoleLog (bool); +void setDebugMode (bool); }; #define _error(...) Logger::log(LOG_ERR, __VA_ARGS__) diff --git a/sflphone-common/src/manager.h b/sflphone-common/src/manager.h index e9324055911b07075cc5ff6420b79b64a5a2c643..df04243699c2ff41a0eab0e0f140f98cb5963ade 100644 --- a/sflphone-common/src/manager.h +++ b/sflphone-common/src/manager.h @@ -1,18 +1,18 @@ /* * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. - * Author : Jean-Philippe Barrette-LaPierre + * Author : Jean-Philippe Barrette-LaPierre * <jean-philippe.barrette-lapierre@savoirfairelinux.com> - * + * * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -37,5 +37,5 @@ typedef utilspp::SingletonHolder<ManagerImpl> Manager; -#endif +#endif diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp index 2362aa513cb21de5cde31cd404507822275b424f..bd71fc84d46e265492042016e12f9ad43255a8eb 100644 --- a/sflphone-common/src/managerimpl.cpp +++ b/sflphone-common/src/managerimpl.cpp @@ -72,13 +72,14 @@ #define MD5_APPEND(pms,buf,len) pj_md5_update(pms, (const pj_uint8_t*)buf, len) -#define find_in_map(X, Y) if((iter = map_cpy.find(X)) != map_cpy.end()) { Y = iter->second; } +// Default account used to get default parametersa if requested by client (to build ne account) +SIPAccount defaultAccount ("default"); ManagerImpl::ManagerImpl (void) : _hasTriedToRegister (false), _config(), _currentCallId2(), _currentCallMutex(), _codecBuilder (NULL), _audiodriver (NULL), _dtmfKey (NULL), _codecDescriptorMap(), _toneMutex(), - _telephoneTone (NULL), _audiofile(), _spkr_volume (0), + _telephoneTone (NULL), _audiofile (NULL), _spkr_volume (0), _mic_volume (0), _mutex(), _dbus (NULL), _waitingCall(), _waitingCallMutex(), _nbIncomingWaitingCall (0), _path (""), _exist (0), _setupLoaded (false), _callAccountMap(), @@ -106,6 +107,11 @@ ManagerImpl::ManagerImpl (void) : // never call if we use only the singleton... ManagerImpl::~ManagerImpl (void) { + if (_audiofile) { + delete _audiofile; + _audiofile = NULL; + } + // terminate(); delete _cleaner; _cleaner = NULL; @@ -118,8 +124,12 @@ ManagerImpl::~ManagerImpl (void) void ManagerImpl::init () { + _debug ("Manager: Init"); + // Load accounts, init map - loadAccountMap(); + buildConfiguration(); + + _debug ("Manager: account map loaded"); initVolume(); @@ -140,7 +150,7 @@ void ManagerImpl::init () unsigned int sampleRate = audiolayer->getSampleRate(); _debugInit ("Manager: Load telephone tone"); - std::string country = getConfigString (PREFERENCES, ZONE_TONE); + std::string country = preferences.getZoneToneChoice(); _telephoneTone = new TelephoneTone (country, sampleRate); _debugInit ("Manager: Loading DTMF key"); @@ -148,7 +158,7 @@ void ManagerImpl::init () } // Load the history - _history->load_history (getConfigInt (PREFERENCES, CONFIG_HISTORY_LIMIT)); + _history->load_history (preferences.getHistoryLimit()); } void ManagerImpl::terminate () @@ -221,13 +231,17 @@ bool ManagerImpl::outgoingCall (const std::string& account_id, Call::CallConfiguration callConfig; SIPVoIPLink *siplink; + if (call_id.empty()) { + _debug ("Manager: New outgoing call abbort, missing callid"); + return false; + } + _debug ("Manager: New outgoing call %s to %s", call_id.c_str(), to.c_str()); CallID current_call_id = getCurrentCallId(); - if (getConfigString (HOOKS, PHONE_NUMBER_HOOK_ENABLED) == "1") - _cleaner->set_phone_number_prefix (getConfigString (HOOKS, - PHONE_NUMBER_HOOK_ADD_PREFIX)); + if (hookPreference.getNumberEnabled()) + _cleaner->set_phone_number_prefix (hookPreference.getNumberAddPrefix()); else _cleaner->set_phone_number_prefix (""); @@ -645,7 +659,7 @@ bool ManagerImpl::transferCall (const CallID& call_id, const std::string& to) AccountID accountid; bool returnValue; - _info ("Manager: Transfer call %s\n", call_id.c_str()); + _info ("Manager: Transfer call %s", call_id.c_str()); CallID current_call_id = getCurrentCallId(); @@ -1389,6 +1403,8 @@ void ManagerImpl::addStream (const CallID& call_id) if (participToConference (call_id)) { + _debug ("Manager: Add stream to conference"); + // bind to conference participant ConferenceMap::iterator iter = _conferencemap.find (call->getConfId()); @@ -1415,6 +1431,8 @@ void ManagerImpl::addStream (const CallID& call_id) } else { + _debug ("Manager: Add stream to call"); + // bind to main getAudioDriver()->getMainBuffer()->bindCallID (call_id); @@ -1445,11 +1463,43 @@ void ManagerImpl::removeStream (const CallID& call_id) //THREAD=Main bool ManagerImpl::saveConfig (void) { - _debug ("Saving Configuration to XDG directory %s ... ", _path.c_str()); - setConfig (AUDIO, VOLUME_SPKR, getSpkrVolume()); - setConfig (AUDIO, VOLUME_MICRO, getMicVolume()); + _debug ("Manager: Saving Configuration to XDG directory %s ... ", _path.c_str()); + audioPreference.setVolumemic (getMicVolume()); + audioPreference.setVolumespkr (getSpkrVolume()); + + AccountMap::iterator iter = _accountMap.begin(); + + try { + // emitter = new Conf::YamlEmitter("sequenceEmitter.yml"); + emitter = new Conf::YamlEmitter (_path.c_str()); + + while (iter != _accountMap.end()) { + _debug ("Manager: Saving account: %s", iter->first.c_str()); + + if (iter->first == "") { + iter++; + continue; + } + + iter->second->serialize (emitter); + iter++; + } - _setupLoaded = _config.saveConfigTree (_path.data()); + preferences.serialize (emitter); + voipPreferences.serialize (emitter); + addressbookPreference.serialize (emitter); + hookPreference.serialize (emitter); + audioPreference.serialize (emitter); + shortcutPreferences.serialize (emitter); + + emitter->serializeData(); + + delete emitter; + } catch (Conf::YamlEmitterException &e) { + _error ("ConfigTree: %s", e.what()); + } + + // _setupLoaded = _config.saveConfigTree(_path.data()); return _setupLoaded; } @@ -1482,7 +1532,7 @@ bool ManagerImpl::playDtmf (char code) stopTone(); - bool hasToPlayTone = getConfigBool (SIGNALISATION, PLAY_DTMF); + bool hasToPlayTone = voipPreferences.getPlayDtmf(); if (!hasToPlayTone) { _debug ("Manager: playDtmf: Do not have to play a tone..."); @@ -1490,7 +1540,7 @@ bool ManagerImpl::playDtmf (char code) } // length in milliseconds - pulselen = getConfigInt (SIGNALISATION, PULSE_LENGTH); + pulselen = voipPreferences.getPulseLength(); if (!pulselen) { _debug ("Manager: playDtmf: Pulse length is not set..."); @@ -1621,7 +1671,7 @@ bool ManagerImpl::incomingCall (Call* call, const AccountID& accountId) _debug ("Manager: Has no current call"); call->setConnectionState (Call::Ringing); - ringtone(); + ringtone (accountId); } else { _debug ("Manager: has current call"); @@ -1828,6 +1878,9 @@ void ManagerImpl::startVoiceMessageNotification (const AccountID& accountId, void ManagerImpl::connectionStatusNotification () { + + _debug ("Manager: connectionStatusNotification"); + if (_dbus != NULL) { _dbus->getConfigurationManager()->accountsChanged(); } @@ -1844,7 +1897,7 @@ bool ManagerImpl::playATone (Tone::TONEID toneId) // _debug ("Manager: Play tone %d", toneId); - hasToPlayTone = getConfigBool (SIGNALISATION, PLAY_TONES); + hasToPlayTone = voipPreferences.getPlayTones(); if (!hasToPlayTone) return false; @@ -1873,7 +1926,7 @@ void ManagerImpl::stopTone () { bool hasToPlayTone; - hasToPlayTone = getConfigBool (SIGNALISATION, PLAY_TONES); + hasToPlayTone = voipPreferences.getPlayTones(); if (!hasToPlayTone) return; @@ -1884,7 +1937,9 @@ void ManagerImpl::stopTone () _telephoneTone->setCurrentTone (Tone::TONE_NULL); } - _audiofile.stop(); + if (_audiofile) + _audiofile->stop(); + _toneMutex.leaveMutex(); } @@ -1925,7 +1980,7 @@ void ManagerImpl::ringback () /** * Multi Thread */ -void ManagerImpl::ringtone () +void ManagerImpl::ringtone (const AccountID& accountID) { std::string ringchoice; AudioLayer *audiolayer; @@ -1935,13 +1990,20 @@ void ManagerImpl::ringtone () _debug ("Manager: Ringtone"); - if (isRingtoneEnabled()) { + Account *account = getAccount (accountID); + + if (!account) { + _warn ("Manager: Warning: invalid account in ringtone"); + return; + } + + if (account->getRingtoneEnabled()) { _debug ("Manager: Tone is enabled"); //TODO Comment this because it makes the daemon crashes since the main thread //synchronizes the ringtone thread. - ringchoice = getConfigString (AUDIO, RING_CHOICE); + ringchoice = account->getRingtonePath(); //if there is no / inside the path if (ringchoice.find (DIR_SEPARATOR_CH) == std::string::npos) { @@ -1960,19 +2022,34 @@ void ManagerImpl::ringtone () layer = audiolayer->getLayerType(); samplerate = audiolayer->getSampleRate(); - codecForTone = _codecDescriptorMap.getFirstCodecAvailable(); _toneMutex.enterMutex(); - loadFile = _audiofile.loadFile (ringchoice, codecForTone, samplerate); + if (_audiofile) { + delete _audiofile; + _audiofile = NULL; + } + + std::string wave (".wav"); + size_t found = ringchoice.find (wave); + + if (found != std::string::npos) + _audiofile = static_cast<AudioFile *> (new WaveFile()); + else + _audiofile = static_cast<AudioFile *> (new RawFile()); + + loadFile = false; + + if (_audiofile) + loadFile = _audiofile->loadFile (ringchoice, codecForTone, samplerate); _toneMutex.leaveMutex(); if (loadFile) { _toneMutex.enterMutex(); - _audiofile.start(); + _audiofile->start(); _toneMutex.leaveMutex(); // start audio if not started AND flush all buffers (main and urgent) @@ -2005,10 +2082,13 @@ ManagerImpl::getTelephoneFile () // _debug("ManagerImpl::getTelephoneFile()"); ost::MutexLock m (_toneMutex); - if (_audiofile.isStarted()) { - return &_audiofile; + if (!_audiofile) + return NULL; + + if (_audiofile->isStarted()) { + return _audiofile; } else { - return 0; + return NULL; } } @@ -2068,7 +2148,7 @@ int ManagerImpl::createSettingsPath (void) } // Load user's configuration - _path = _path + DIR_SEPARATOR_STR + PROGNAME + "rc"; + _path = _path + DIR_SEPARATOR_STR + PROGNAME + ".yml"; return 1; } @@ -2078,246 +2158,88 @@ int ManagerImpl::createSettingsPath (void) */ void ManagerImpl::initConfigFile (bool load_user_value, std::string alternate) { - _debug ("Manager: InitConfigFile"); - - // Default values, that will be overwritten by the call to - // 'populateFromFile' below. - - // Peer to peer settings - _config.addDefaultValue (std::pair<std::string, std::string> (SRTP_ENABLE, - FALSE_STR), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - SRTP_RTP_FALLBACK, FALSE_STR), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - SRTP_KEY_EXCHANGE, "1"), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - ZRTP_HELLO_HASH, TRUE_STR), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - ZRTP_DISPLAY_SAS, TRUE_STR), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - ZRTP_DISPLAY_SAS_ONCE, FALSE_STR), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - ZRTP_NOT_SUPP_WARNING, TRUE_STR), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - TLS_LISTENER_PORT, DEFAULT_SIP_TLS_PORT), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> (TLS_ENABLE, - FALSE_STR), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - TLS_CA_LIST_FILE, EMPTY_FIELD), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - TLS_CERTIFICATE_FILE, EMPTY_FIELD), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - TLS_PRIVATE_KEY_FILE, EMPTY_FIELD), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> (TLS_PASSWORD, - EMPTY_FIELD), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> (TLS_METHOD, - "TLSv1"), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> (TLS_CIPHERS, - EMPTY_FIELD), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - TLS_SERVER_NAME, EMPTY_FIELD), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - TLS_VERIFY_SERVER, TRUE_STR), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - TLS_VERIFY_CLIENT, TRUE_STR), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - TLS_REQUIRE_CLIENT_CERTIFICATE, TRUE_STR), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - TLS_NEGOTIATION_TIMEOUT_SEC, "2"), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - TLS_NEGOTIATION_TIMEOUT_MSEC, "0"), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - LOCAL_INTERFACE, "default"), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - PUBLISHED_SAMEAS_LOCAL, TRUE_STR), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> (LOCAL_PORT, - DEFAULT_SIP_PORT), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> (PUBLISHED_PORT, - DEFAULT_SIP_PORT), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - PUBLISHED_ADDRESS, DEFAULT_ADDRESS), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> (STUN_ENABLE, - DFT_STUN_ENABLE), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> (STUN_SERVER, - DFT_STUN_SERVER), IP2IP_PROFILE); - _config.addDefaultValue (std::pair<std::string, std::string> ( - CONFIG_ACCOUNT_ALIAS, EMPTY_FIELD), IP2IP_PROFILE); + + _debug ("Manager: Init config file"); // Init display name to the username under which // this sflphone instance is running. - std::string diplayName (""); uid_t uid = getuid(); struct passwd * user_info = NULL; user_info = getpwuid (uid); - if (user_info != NULL) { - diplayName = user_info->pw_name; - } - - _config.addDefaultValue (std::pair<std::string, std::string> (DISPLAY_NAME, - diplayName), IP2IP_PROFILE); - - // Signalisation settings - _config.addDefaultValue (std::pair<std::string, std::string> (SYMMETRIC, - TRUE_STR), SIGNALISATION); - _config.addDefaultValue (std::pair<std::string, std::string> (PLAY_DTMF, - TRUE_STR), SIGNALISATION); - _config.addDefaultValue (std::pair<std::string, std::string> (PLAY_TONES, - TRUE_STR), SIGNALISATION); - _config.addDefaultValue (std::pair<std::string, std::string> (PULSE_LENGTH, - DFT_PULSE_LENGTH_STR), SIGNALISATION); - _config.addDefaultValue (std::pair<std::string, std::string> (SEND_DTMF_AS, - SIP_INFO_STR), SIGNALISATION); - _config.addDefaultValue (std::pair<std::string, std::string> (ZRTP_ZIDFILE, - ZRTP_ZID_FILENAME), SIGNALISATION); - - // Audio settings - _config.addDefaultValue (std::pair<std::string, std::string> ( - ALSA_CARD_ID_IN, ALSA_DFT_CARD), AUDIO); - _config.addDefaultValue (std::pair<std::string, std::string> ( - ALSA_CARD_ID_OUT, ALSA_DFT_CARD), AUDIO); - _config.addDefaultValue (std::pair<std::string, std::string> ( - ALSA_CARD_ID_RING, ALSA_DFT_CARD), AUDIO); - _config.addDefaultValue (std::pair<std::string, std::string> ( - AUDIO_SAMPLE_RATE, DFT_SAMPLE_RATE), AUDIO); - _config.addDefaultValue (std::pair<std::string, std::string> ( - ALSA_FRAME_SIZE, DFT_FRAME_SIZE), AUDIO); - _config.addDefaultValue (std::pair<std::string, std::string> (ALSA_PLUGIN, - PCM_DEFAULT), AUDIO); - _config.addDefaultValue (std::pair<std::string, std::string> (RING_CHOICE, - DFT_RINGTONE), AUDIO); - _config.addDefaultValue (std::pair<std::string, std::string> (VOLUME_SPKR, - DFT_VOL_SPKR_STR), AUDIO); - _config.addDefaultValue (std::pair<std::string, std::string> (VOLUME_MICRO, - DFT_VOL_MICRO_STR), AUDIO); - _config.addDefaultValue (std::pair<std::string, std::string> (RECORD_PATH, - DFT_RECORD_PATH), AUDIO); - - // Pulseaudio stream device - _config.addDefaultValue (std::pair<std::string, std::string> (PULSE_DEVICE_PLAYBACK, ""), AUDIO); - _config.addDefaultValue (std::pair<std::string, std::string> (PULSE_DEVICE_RECORD, ""), AUDIO); - _config.addDefaultValue (std::pair<std::string, std::string> (PULSE_DEVICE_RINGTONE, ""), AUDIO); - - - // General settings - _config.addDefaultValue (std::pair<std::string, std::string> (ZONE_TONE, - DFT_ZONE), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> ( - CONFIG_RINGTONE, TRUE_STR), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> (CONFIG_DIALPAD, - TRUE_STR), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> ( - CONFIG_SEARCHBAR, TRUE_STR), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> (CONFIG_START, - FALSE_STR), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> (CONFIG_POPUP, - TRUE_STR), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> (CONFIG_NOTIFY, - TRUE_STR), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> ( - CONFIG_MAIL_NOTIFY, FALSE_STR), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> (CONFIG_VOLUME, - TRUE_STR), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> ( - CONFIG_HISTORY_LIMIT, DFT_HISTORY_LIMIT), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> ( - CONFIG_HISTORY_ENABLED, TRUE_STR), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> (CONFIG_AUDIO, - DFT_AUDIO_MANAGER), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> ( - CONFIG_SIP_PORT, DFT_SIP_PORT), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> ( - CONFIG_ACCOUNTS_ORDER, EMPTY_FIELD), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> (CONFIG_MD5HASH, - FALSE_STR), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> (WINDOW_WIDTH, - DFT_WINDOW_WIDTH), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> (WINDOW_HEIGHT, - DFT_WINDOW_HEIGHT), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> ( - WINDOW_POSITION_X, "0"), PREFERENCES); - _config.addDefaultValue (std::pair<std::string, std::string> ( - WINDOW_POSITION_Y, "0"), PREFERENCES); - - // Addressbook settings - _config.addDefaultValue (std::pair<std::string, std::string> ( - ADDRESSBOOK_ENABLE, TRUE_STR), ADDRESSBOOK); - _config.addDefaultValue (std::pair<std::string, std::string> ( - ADDRESSBOOK_MAX_RESULTS, "25"), ADDRESSBOOK); - _config.addDefaultValue (std::pair<std::string, std::string> ( - ADDRESSBOOK_DISPLAY_CONTACT_PHOTO, FALSE_STR), ADDRESSBOOK); - _config.addDefaultValue (std::pair<std::string, std::string> ( - ADDRESSBOOK_DISPLAY_PHONE_BUSINESS, TRUE_STR), ADDRESSBOOK); - _config.addDefaultValue (std::pair<std::string, std::string> ( - ADDRESSBOOK_DISPLAY_PHONE_HOME, FALSE_STR), ADDRESSBOOK); - _config.addDefaultValue (std::pair<std::string, std::string> ( - ADDRESSBOOK_DISPLAY_PHONE_MOBILE, FALSE_STR), ADDRESSBOOK); - - // Hooks settings - _config.addDefaultValue (std::pair<std::string, std::string> ( - URLHOOK_SIP_FIELD, HOOK_DEFAULT_SIP_FIELD), HOOKS); - _config.addDefaultValue (std::pair<std::string, std::string> ( - URLHOOK_COMMAND, HOOK_DEFAULT_URL_COMMAND), HOOKS); - _config.addDefaultValue (std::pair<std::string, std::string> ( - URLHOOK_SIP_ENABLED, FALSE_STR), HOOKS); - _config.addDefaultValue (std::pair<std::string, std::string> ( - URLHOOK_IAX2_ENABLED, FALSE_STR), HOOKS); - _config.addDefaultValue (std::pair<std::string, std::string> ( - PHONE_NUMBER_HOOK_ENABLED, FALSE_STR), HOOKS); - _config.addDefaultValue (std::pair<std::string, std::string> ( - PHONE_NUMBER_HOOK_ADD_PREFIX, EMPTY_FIELD), HOOKS); - std::string path; - // Loads config from ~/.sflphone/sflphonedrc or so.. + // Loads config from ~/.sflphone/sflphoned.yml or so.. if (createSettingsPath() == 1 && load_user_value) { + (alternate == "") ? path = _path : path = alternate; std::cout << path << std::endl; _exist = _config.populateFromFile (path); } - // Globally shared default values (not to be populated from file) - _config.addDefaultValue (std::pair<std::string, std::string> (HOSTNAME, - EMPTY_FIELD)); + _debug ("Manager: configuration file path: %s", path.c_str()); - _config.addDefaultValue (std::pair<std::string, std::string> ( - AUTHENTICATION_USERNAME, EMPTY_FIELD)); - _config.addDefaultValue (std::pair<std::string, std::string> (USERNAME, - EMPTY_FIELD)); + bool fileExist = true; + bool out = false; - _config.addDefaultValue (std::pair<std::string, std::string> (PASSWORD, - EMPTY_FIELD)); + if (path.empty()) { + _error ("Manager: Error: XDG config file path is empty!"); + fileExist = false; + } - _config.addDefaultValue (std::pair<std::string, std::string> (REALM, - DEFAULT_REALM)); + std::fstream file; - _config.addDefaultValue (std::pair<std::string, std::string> (USERAGENT, - DFT_USERAGENT)); + file.open (path.data(), std::fstream::in); - _config.addDefaultValue (std::pair<std::string, std::string> ( - CONFIG_ACCOUNT_REGISTRATION_EXPIRE, DFT_EXPIRE_VALUE)); + if (!file.is_open()) { - _config.addDefaultValue (std::pair<std::string, std::string> ( - CONFIG_ACCOUNT_RESOLVE_ONCE, FALSE_STR)); + _debug ("Manager: File %s not opened, create new one", path.c_str()); + file.open (path.data(), std::fstream::out); + out = true; - _config.addDefaultValue (std::pair<std::string, std::string> ( - CONFIG_ACCOUNT_ALIAS, EMPTY_FIELD)); + if (!file.is_open()) { + _error ("Manager: Error: could not create empty configurationfile!"); + fileExist = false; + } + + file.close(); - _config.addDefaultValue (std::pair<std::string, std::string> ( - CONFIG_ACCOUNT_MAILBOX, EMPTY_FIELD)); + fileExist = false; + } - _config.addDefaultValue (std::pair<std::string, std::string> ( - CONFIG_ACCOUNT_ENABLE, TRUE_STR)); + // get length of file: + file.seekg (0, std::ios::end); + int length = file.tellg(); - _config.addDefaultValue (std::pair<std::string, std::string> ( - CONFIG_CREDENTIAL_NUMBER, "0")); + file.seekg (0, std::ios::beg); + + if (length <= 0) { + _debug ("Manager: Configuration file length is empty", length); + file.close(); + fileExist = false; // should load config + } - _config.addDefaultValue (std::pair<std::string, std::string> ( - CONFIG_ACCOUNT_TYPE, DEFAULT_ACCOUNT_TYPE)); + if (fileExist) { + try { - _setupLoaded = (_exist == 2) ? false : true; + // parser = new Conf::YamlParser("sequenceParser.yml"); + parser = new Conf::YamlParser (_path.c_str()); + + parser->serializeEvents(); + + parser->composeEvents(); + + parser->constructNativeData(); + + _setupLoaded = true; + + _debug ("Manager: Configuration file parsed successfully"); + } catch (Conf::YamlParserException &e) { + _error ("Manager: %s", e.what()); + } + } } /** @@ -2339,8 +2261,8 @@ void ManagerImpl::initAudioCodec (void) std::vector<std::string> ManagerImpl::retrieveActiveCodecs () { - // This property is now set per account basis - std::string s = getConfigString (AUDIO, "ActiveCodecs"); + // This property is now set per account basis so we should remove it... + std::string s = ""; _info ("Manager: Retrieve active codecs: %s", s.c_str ()); return unserialize (s); } @@ -2393,63 +2315,25 @@ std::string ManagerImpl::getCurrentCodecName (const CallID& id) /** * Set input audio plugin */ -void ManagerImpl::setInputAudioPlugin (const std::string& audioPlugin) +void ManagerImpl::setAudioPlugin (const std::string& audioPlugin) { int layer = _audiodriver -> getLayerType(); + audioPreference.setPlugin (audioPlugin); + if (CHECK_INTERFACE (layer , ALSA)) { _debug ("Set input audio plugin"); _audiodriver -> setErrorMessage (-1); _audiodriver -> openDevice (_audiodriver->getIndexIn(), _audiodriver->getIndexOut(), _audiodriver->getIndexRing(), _audiodriver -> getSampleRate(), - _audiodriver -> getFrameSize(), SFL_PCM_CAPTURE, audioPlugin); + _audiodriver -> getFrameSize(), SFL_PCM_BOTH, audioPlugin); if (_audiodriver -> getErrorMessage() != -1) notifyErrClient (_audiodriver -> getErrorMessage()); - } else { } } -/** - * Set output audio plugin - */ -void ManagerImpl::setOutputAudioPlugin (const std::string& audioPlugin) -{ - - int res; - - _debug ("Manager: Set output audio plugin"); - _audiodriver -> setErrorMessage (-1); - res = _audiodriver -> openDevice (_audiodriver->getIndexIn(), _audiodriver->getIndexOut(), - _audiodriver->getIndexRing(), _audiodriver -> getSampleRate(), - _audiodriver -> getFrameSize(), SFL_PCM_BOTH, audioPlugin); - - if (_audiodriver -> getErrorMessage() != -1) - notifyErrClient (_audiodriver -> getErrorMessage()); - - // set config - if (res) - setConfig (AUDIO, ALSA_PLUGIN, audioPlugin); -} - -/** - * Get list of supported audio output device - */ -std::vector<std::string> ManagerImpl::getAudioOutputDeviceList (void) -{ - _debug ("Manager: Get audio output device list"); - AlsaLayer *layer; - std::vector<std::string> devices; - - layer = dynamic_cast<AlsaLayer*> (getAudioDriver()); - - if (layer) - devices = layer -> getSoundCardsInfo (SFL_PCM_PLAYBACK); - - return devices; -} - /** * Set audio output device */ @@ -2478,21 +2362,21 @@ void ManagerImpl::setAudioDevice (const int index, int streamType) _audiodriver->openDevice (_audiodriver->getIndexIn(), index, _audiodriver->getIndexRing(), _audiodriver->getSampleRate(), _audiodriver->getFrameSize(), SFL_PCM_PLAYBACK, alsaplugin); - setConfig (AUDIO, ALSA_CARD_ID_OUT, index); + audioPreference.setCardout (index); break; case SFL_PCM_CAPTURE: _debug ("Manager: Set input device"); _audiodriver->openDevice (index, _audiodriver->getIndexOut(), _audiodriver->getIndexRing(), _audiodriver->getSampleRate(), _audiodriver->getFrameSize(), SFL_PCM_CAPTURE, alsaplugin); - setConfig (AUDIO, ALSA_CARD_ID_IN, index); + audioPreference.setCardin (index); break; case SFL_PCM_RINGTONE: _debug ("Manager: Set ringtone device"); _audiodriver->openDevice (_audiodriver->getIndexOut(), _audiodriver->getIndexOut(), index, _audiodriver->getSampleRate(), _audiodriver->getFrameSize(), SFL_PCM_RINGTONE, alsaplugin); - setConfig (AUDIO, ALSA_CARD_ID_RING, index); + audioPreference.setCardring (index); break; default: _warn ("Unknown stream type"); @@ -2503,6 +2387,24 @@ void ManagerImpl::setAudioDevice (const int index, int streamType) } +/** + * Get list of supported audio output device + */ +std::vector<std::string> ManagerImpl::getAudioOutputDeviceList (void) +{ + _debug ("Manager: Get audio output device list"); + AlsaLayer *layer; + std::vector<std::string> devices; + + layer = dynamic_cast<AlsaLayer*> (getAudioDriver()); + + if (layer) + devices = layer -> getSoundCardsInfo (SFL_PCM_PLAYBACK); + + return devices; +} + + /** * Get list of supported audio input device */ @@ -2545,22 +2447,45 @@ int ManagerImpl::isIax2Enabled (void) #endif } -int ManagerImpl::isRingtoneEnabled (void) +int ManagerImpl::isRingtoneEnabled (const AccountID& id) { - return (getConfigString (PREFERENCES, CONFIG_RINGTONE) == "true") ? 1 : 0; + Account *account = getAccount (id); + + if (!account) { + _warn ("Manager: Warning: invalid account in ringtone enabled"); + return 0; + } + + return account->getRingtoneEnabled() ? 1 : 0; } -void ManagerImpl::ringtoneEnabled (void) +void ManagerImpl::ringtoneEnabled (const AccountID& id) { - (getConfigString (PREFERENCES, CONFIG_RINGTONE) == RINGTONE_ENABLED) ? setConfig ( - PREFERENCES, CONFIG_RINGTONE, FALSE_STR) - : setConfig (PREFERENCES, CONFIG_RINGTONE, TRUE_STR); + + Account *account = getAccount (id); + + if (!account) { + _warn ("Manager: Warning: invalid account in ringtone enabled"); + return; + } + + account->getRingtoneEnabled() ? account->setRingtoneEnabled (false) : account->setRingtoneEnabled (true); + } -std::string ManagerImpl::getRingtoneChoice (void) +std::string ManagerImpl::getRingtoneChoice (const AccountID& id) { + + // retreive specified account id + Account *account = getAccount (id); + + if (!account) { + _warn ("Manager: Warning: Not a valid account ID for ringone choice"); + return std::string (""); + } + // we need the absolute path - std::string tone_name = getConfigString (AUDIO, RING_CHOICE); + std::string tone_name = account->getRingtonePath(); std::string tone_path; if (tone_name.find (DIR_SEPARATOR_CH) == std::string::npos) { @@ -2572,193 +2497,107 @@ std::string ManagerImpl::getRingtoneChoice (void) tone_path = tone_name; } - _debug ("%s", tone_path.c_str()); + _debug ("Manager: get ringtone path %s", tone_path.c_str()); return tone_path; } -void ManagerImpl::setRingtoneChoice (const std::string& tone) +void ManagerImpl::setRingtoneChoice (const std::string& tone, const AccountID& id) { + + _debug ("Manager: Set ringtone path %s to account", tone.c_str()); + + // retreive specified account id + Account *account = getAccount (id); + + if (!account) { + _warn ("Manager: Warning: Not a valid account ID for ringtone choice"); + return; + } + // we save the absolute path - setConfig (AUDIO, RING_CHOICE, tone); + account->setRingtonePath (tone); } std::string ManagerImpl::getRecordPath (void) { - return getConfigString (AUDIO, RECORD_PATH); + return audioPreference.getRecordpath(); } void ManagerImpl::setRecordPath (const std::string& recPath) { - _debug ("ManagerImpl::setRecordPath(%s)! ", recPath.c_str()); - setConfig (AUDIO, RECORD_PATH, recPath); + _debug ("Manager: Set record path %s", recPath.c_str()); + audioPreference.setRecordpath (recPath); } bool ManagerImpl::getMd5CredentialHashing (void) { - return getConfigBool (PREFERENCES, CONFIG_MD5HASH); + return preferences.getMd5Hash(); } -int ManagerImpl::getDialpad (void) -{ - if (getConfigString (PREFERENCES, CONFIG_DIALPAD) == TRUE_STR) { - return 1; - } else { - return 0; - } -} -void ManagerImpl::setDialpad (bool display) -{ - std::string set; - - display ? set = TRUE_STR : set = FALSE_STR; - // If the value we received is different from the one saved in the config file, save the new value - // Else do nothing - - if ( (display && (getConfigString (PREFERENCES, CONFIG_DIALPAD) != TRUE_STR)) - || (!display && (getConfigString (PREFERENCES, CONFIG_DIALPAD) - != FALSE_STR))) - setConfig (PREFERENCES, CONFIG_DIALPAD, set); -} - -int ManagerImpl::getVolumeControls (void) -{ - if (getConfigString (PREFERENCES, CONFIG_VOLUME) == TRUE_STR) { - return 1; - } else { - return 0; - } -} - -void ManagerImpl::setVolumeControls (bool display) -{ - std::string set; - - display ? set = TRUE_STR : set = FALSE_STR; - // If the value we received is different from the one saved in the config file, save the new value - // Else do nothing - - if ( (display && (getConfigString (PREFERENCES, CONFIG_VOLUME) != TRUE_STR)) - || (!display && (getConfigString (PREFERENCES, CONFIG_VOLUME) - != FALSE_STR))) - setConfig (PREFERENCES, CONFIG_VOLUME, set); -} void ManagerImpl::setRecordingCall (const CallID& id) { - /* - _debug ("ManagerImpl::setRecording()! "); - AccountID accountid = getAccountFromCall (id); - - getAccountLink (accountid)->setRecording (id); - */ - AccountID accountid = getAccountFromCall (id); - Recordable* rec = (Recordable *) getAccountLink (accountid)->getCall (id); + Recordable* rec = NULL; - rec->setRecording(); + if (!isConference (id)) { + _debug ("Manager: Set recording for call %s", id.c_str()); + AccountID accountid = getAccountFromCall (id); + rec = (Recordable *) getAccountLink (accountid)->getCall (id); + } else { + _debug ("Manager: Ser recording for conference %s", id.c_str()); + ConferenceMap::iterator it = _conferencemap.find (id); + rec = (Recordable *) it->second; + } + if (rec) + rec->setRecording(); } bool ManagerImpl::isRecording (const CallID& id) { - /* - _debug ("ManagerImpl::isRecording()! "); - AccountID accountid = getAccountFromCall (id); - - return getAccountLink (accountid)->isRecording (id); - */ AccountID accountid = getAccountFromCall (id); Recordable* rec = (Recordable*) getAccountLink (accountid)->getCall (id); - return rec->isRecording(); -} + bool ret = false; -void ManagerImpl::startHidden (void) -{ - (getConfigString (PREFERENCES, CONFIG_START) == START_HIDDEN) ? setConfig ( - PREFERENCES, CONFIG_START, FALSE_STR) : setConfig (PREFERENCES, - CONFIG_START, TRUE_STR); -} + if (rec) + ret = rec->isRecording(); -int ManagerImpl::isStartHidden (void) -{ - return (getConfigBool (PREFERENCES, CONFIG_START) == true) ? 1 : 0; + return ret; } -void ManagerImpl::switchPopupMode (void) -{ - (getConfigString (PREFERENCES, CONFIG_POPUP) == WINDOW_POPUP) ? setConfig ( - PREFERENCES, CONFIG_POPUP, FALSE_STR) : setConfig (PREFERENCES, - CONFIG_POPUP, TRUE_STR); -} void ManagerImpl::setHistoryLimit (const int& days) { - setConfig (PREFERENCES, CONFIG_HISTORY_LIMIT, days); + preferences.setHistoryLimit (days); } int ManagerImpl::getHistoryLimit (void) { - return getConfigInt (PREFERENCES, CONFIG_HISTORY_LIMIT); -} - -std::string ManagerImpl::getHistoryEnabled (void) -{ - return getConfigString (PREFERENCES, CONFIG_HISTORY_ENABLED); -} - -void ManagerImpl::setHistoryEnabled (void) -{ - (getConfigString (PREFERENCES, CONFIG_HISTORY_ENABLED) == TRUE_STR) ? setConfig ( - PREFERENCES, CONFIG_HISTORY_ENABLED, FALSE_STR) - : setConfig (PREFERENCES, CONFIG_HISTORY_ENABLED, TRUE_STR); + return preferences.getHistoryLimit(); } -int ManagerImpl::getSearchbar (void) -{ - return getConfigInt (PREFERENCES, CONFIG_SEARCHBAR); -} - -void ManagerImpl::setSearchbar (void) -{ - (getConfigInt (PREFERENCES, CONFIG_SEARCHBAR) == 1) ? setConfig (PREFERENCES, - CONFIG_SEARCHBAR, FALSE_STR) : setConfig (PREFERENCES, - CONFIG_SEARCHBAR, TRUE_STR); -} - -int ManagerImpl::popupMode (void) -{ - return (getConfigBool (PREFERENCES, CONFIG_POPUP) == true) ? 1 : 0; -} - -int32_t ManagerImpl::getNotify (void) -{ - return (getConfigBool (PREFERENCES, CONFIG_NOTIFY) == true) ? 1 : 0; -} - -void ManagerImpl::setNotify (void) +int32_t ManagerImpl::getMailNotify (void) { - (getConfigString (PREFERENCES, CONFIG_NOTIFY) == NOTIFY_ALL) ? setConfig ( - PREFERENCES, CONFIG_NOTIFY, FALSE_STR) : setConfig (PREFERENCES, - CONFIG_NOTIFY, TRUE_STR); + return preferences.getNotifyMails(); } -int32_t ManagerImpl::getMailNotify (void) +void ManagerImpl::setMailNotify (void) { - return getConfigInt (PREFERENCES, CONFIG_MAIL_NOTIFY); + preferences.getNotifyMails() ? preferences.setNotifyMails (true) : preferences.setNotifyMails (false); } void ManagerImpl::setAudioManager (const int32_t& api) { int type; - std::string alsaPlugin; - _debug ("Setting audio manager "); + _debug ("Manager: Setting audio manager "); if (!_audiodriver) return; @@ -2766,11 +2605,11 @@ void ManagerImpl::setAudioManager (const int32_t& api) type = _audiodriver->getLayerType(); if (type == api) { - _debug ("Audio manager chosen already in use. No changes made. "); + _debug ("Manager: Audio manager chosen already in use. No changes made. "); return; } - setConfig (PREFERENCES, CONFIG_AUDIO, api); + preferences.setAudioApi (api); switchAudioManager(); return; @@ -2779,20 +2618,14 @@ void ManagerImpl::setAudioManager (const int32_t& api) int32_t ManagerImpl::getAudioManager (void) { - return getConfigInt (PREFERENCES, CONFIG_AUDIO); + return preferences.getAudioApi(); } -void ManagerImpl::setMailNotify (void) -{ - (getConfigString (PREFERENCES, CONFIG_MAIL_NOTIFY) == NOTIFY_ALL) ? setConfig ( - PREFERENCES, CONFIG_MAIL_NOTIFY, FALSE_STR) - : setConfig (PREFERENCES, CONFIG_MAIL_NOTIFY, TRUE_STR); -} void ManagerImpl::notifyErrClient (const int32_t& errCode) { if (_dbus) { - _debug ("NOTIFY ERR NUMBER %i" , errCode); + _debug ("Manager: NOTIFY ERR NUMBER %i" , errCode); _dbus -> getConfigurationManager() -> errorAlert (errCode); } } @@ -2801,7 +2634,7 @@ int ManagerImpl::getAudioDeviceIndex (const std::string name) { AlsaLayer *alsalayer; - _debug ("Get audio device index"); + _debug ("Manager: Get audio device index"); alsalayer = dynamic_cast<AlsaLayer *> (getAudioDriver()); @@ -2815,33 +2648,23 @@ std::string ManagerImpl::getCurrentAudioOutputPlugin (void) { AlsaLayer *alsalayer; - _debug ("Get alsa plugin"); + _debug ("Manager: Get alsa plugin"); alsalayer = dynamic_cast<AlsaLayer *> (getAudioDriver()); - if (alsalayer) - return alsalayer -> getAudioPlugin(); - else - return getConfigString (AUDIO, ALSA_PLUGIN); + // if (alsalayer) + // return alsalayer -> getAudioPlugin(); + // else + return audioPreference.getPlugin(); } std::string ManagerImpl::getEchoCancelState (void) { - // echo canceller is disabled by default - bool isEnabled = false; - - if (_audiodriver) { - isEnabled = _audiodriver->getEchoCancelState(); - } + std::string state; - std::string state (""); - - if (isEnabled) - state = "enabled"; - else - state = "disabled"; + state = audioPreference.getEchoCancel() ? "enabled" : "disabled"; return state; } @@ -2850,12 +2673,9 @@ void ManagerImpl::setEchoCancelState (std::string state) { _debug ("Manager: Set echo suppress state: %s", state.c_str()); - bool isEnabled = false; + bool isEnabled = state == "enabled" ? true : false; - if (state.compare ("enabled") == 0) - isEnabled = true; - else - isEnabled = false; + audioPreference.setEchoCancel (isEnabled); if (_audiodriver) { _audiodriver->setEchoCancelState (isEnabled); @@ -2867,18 +2687,9 @@ std::string ManagerImpl::getNoiseSuppressState (void) { // noise suppress disabled by default - bool isEnabled = false; + std::string state; - if (_audiodriver) { - isEnabled = _audiodriver->getNoiseSuppressState(); - } - - std::string state (""); - - if (isEnabled) - state = "enabled"; - else - state = "disabled"; + state = audioPreference.getNoiseReduce() ? "enabled" : "disabled"; return state; } @@ -2887,12 +2698,9 @@ void ManagerImpl::setNoiseSuppressState (std::string state) { _debug ("Manager: Set noise suppress state: %s", state.c_str()); - bool isEnabled = false; + bool isEnabled = state == "enabled" ? true : false; - if (state.compare ("enabled") == 0) - isEnabled = true; - else - isEnabled = false; + audioPreference.setNoiseReduce (isEnabled); if (_audiodriver) { _audiodriver->setNoiseSuppressState (isEnabled); @@ -2917,16 +2725,16 @@ bool ManagerImpl::initAudioDriver (void) _debugInit ("AudioLayer Creation"); - if (getConfigInt (PREFERENCES, CONFIG_AUDIO) == ALSA) { + if (preferences.getAudioApi() == ALSA) { _audiodriver = new AlsaLayer (this); _audiodriver->setMainBuffer (&_mainBuffer); - } else if (getConfigInt (PREFERENCES, CONFIG_AUDIO) == PULSEAUDIO) { + } else if (preferences.getAudioApi() == PULSEAUDIO) { if (app_is_running ("pulseaudio") == 0) { _audiodriver = new PulseLayer (this); _audiodriver->setMainBuffer (&_mainBuffer); } else { _audiodriver = new AlsaLayer (this); - setConfig (PREFERENCES, CONFIG_AUDIO, ALSA); + preferences.setAudioApi (ALSA); _audiodriver->setMainBuffer (&_mainBuffer); } } else @@ -2961,13 +2769,13 @@ void ManagerImpl::selectAudioDriver (void) _debug ("Audio layer type: %i" , layer); /* Retrieve the global devices info from the user config */ - alsaPlugin = getConfigString (AUDIO, ALSA_PLUGIN); - numCardIn = getConfigInt (AUDIO, ALSA_CARD_ID_IN); - numCardOut = getConfigInt (AUDIO, ALSA_CARD_ID_OUT); - numCardRing = getConfigInt (AUDIO, ALSA_CARD_ID_RING); - // sampleRate = getConfigInt(AUDIO, AUDIO_SAMPLE_RATE); + alsaPlugin = audioPreference.getPlugin(); + numCardIn = audioPreference.getCardin(); + numCardOut = audioPreference.getCardout(); + numCardRing = audioPreference.getCardring(); + sampleRate = _mainBuffer.getInternalSamplingRate(); - frameSize = getConfigInt (AUDIO, ALSA_FRAME_SIZE); + frameSize = audioPreference.getFramesize(); /* Only for the ALSA layer, we check the sound card information */ @@ -2977,19 +2785,19 @@ void ManagerImpl::selectAudioDriver (void) if (!alsalayer -> soundCardIndexExist (numCardIn, SFL_PCM_CAPTURE)) { _debug (" Card with index %i doesn't exist or cannot capture. Switch to 0.", numCardIn); numCardIn = ALSA_DFT_CARD_ID; - setConfig (AUDIO, ALSA_CARD_ID_IN, ALSA_DFT_CARD_ID); + audioPreference.setCardin (ALSA_DFT_CARD_ID); } if (!alsalayer -> soundCardIndexExist (numCardOut, SFL_PCM_PLAYBACK)) { _debug (" Card with index %i doesn't exist or cannot playback. Switch to 0.", numCardOut); numCardOut = ALSA_DFT_CARD_ID; - setConfig (AUDIO, ALSA_CARD_ID_OUT, ALSA_DFT_CARD_ID); + audioPreference.setCardout (ALSA_DFT_CARD_ID); } if (!alsalayer->soundCardIndexExist (numCardRing, SFL_PCM_RINGTONE)) { _debug (" Card with index %i doesn't exist or cannot ringtone. Switch to 0.", numCardRing); numCardRing = ALSA_DFT_CARD_ID; - setConfig (AUDIO, ALSA_CARD_ID_RING, ALSA_DFT_CARD_ID); + audioPreference.setCardring (ALSA_DFT_CARD_ID); } } @@ -3018,17 +2826,16 @@ void ManagerImpl::switchAudioManager (void) type = _audiodriver->getLayerType(); - // samplerate = getConfigInt(AUDIO, AUDIO_SAMPLE_RATE); samplerate = _mainBuffer.getInternalSamplingRate(); - framesize = getConfigInt (AUDIO, ALSA_FRAME_SIZE); + framesize = audioPreference.getFramesize(); - _debug ("Mnager: samplerate: %i, framesize %i\n", samplerate, framesize); + _debug ("Manager: samplerate: %i, framesize %i", samplerate, framesize); - alsaPlugin = getConfigString (AUDIO, ALSA_PLUGIN); + alsaPlugin = audioPreference.getPlugin(); - numCardIn = getConfigInt (AUDIO, ALSA_CARD_ID_IN); - numCardOut = getConfigInt (AUDIO, ALSA_CARD_ID_OUT); - numCardRing = getConfigInt (AUDIO, ALSA_CARD_ID_RING); + numCardIn = audioPreference.getCardin(); + numCardOut = audioPreference.getCardout(); + numCardRing = audioPreference.getCardring(); _debug ("Manager: Deleting current layer... "); @@ -3098,15 +2905,15 @@ void ManagerImpl::audioSamplingRateChanged (void) type = _audiodriver->getLayerType(); samplerate = _mainBuffer.getInternalSamplingRate(); - framesize = getConfigInt (AUDIO, ALSA_FRAME_SIZE); + framesize = audioPreference.getFramesize(); - _debug ("Mnager: samplerate: %i, framesize %i\n", samplerate, framesize); + _debug ("Mnager: samplerate: %i, framesize %i", samplerate, framesize); - alsaPlugin = getConfigString (AUDIO, ALSA_PLUGIN); + alsaPlugin = audioPreference.getPlugin(); - numCardIn = getConfigInt (AUDIO, ALSA_CARD_ID_IN); - numCardOut = getConfigInt (AUDIO, ALSA_CARD_ID_OUT); - numCardRing = getConfigInt (AUDIO, ALSA_CARD_ID_RING); + numCardIn = audioPreference.getCardin(); + numCardOut = audioPreference.getCardout(); + numCardRing = audioPreference.getCardring(); _debug ("Manager: Deleting current layer... "); @@ -3154,7 +2961,7 @@ void ManagerImpl::audioSamplingRateChanged (void) delete _telephoneTone; _debugInit ("Manager: Load telephone tone"); - std::string country = getConfigString (PREFERENCES, ZONE_TONE); + std::string country = preferences.getZoneToneChoice(); _telephoneTone = new TelephoneTone (country, sampleRate); @@ -3185,8 +2992,8 @@ void ManagerImpl::audioSamplingRateChanged (void) void ManagerImpl::initVolume () { _debugInit ("Initiate Volume"); - setSpkrVolume (getConfigInt (AUDIO, VOLUME_SPKR)); - setMicVolume (getConfigInt (AUDIO, VOLUME_MICRO)); + setSpkrVolume (audioPreference.getVolumespkr()); + setMicVolume (audioPreference.getVolumemic()); } void ManagerImpl::setSpkrVolume (unsigned short spkr_vol) @@ -3215,7 +3022,7 @@ void ManagerImpl::setMicVolume (unsigned short mic_vol) int ManagerImpl::getLocalIp2IpPort (void) { // The SIP port used for default account (IP to IP) calls= - return getConfigInt (IP2IP_PROFILE, LOCAL_PORT); + return preferences.getPortNum(); } @@ -3382,7 +3189,7 @@ std::string ManagerImpl::getConfigString (const std::string& section, bool ManagerImpl::setConfig (const std::string& section, const std::string& name, const std::string& value) { - // _debug ("ManagerImpl::setConfig %s %s %s", section.c_str(), name.c_str(), value.c_str()); + return _config.setConfigTreeItem (section, name, value); } @@ -3397,9 +3204,10 @@ bool ManagerImpl::setConfig (const std::string& section, void ManagerImpl::setAccountsOrder (const std::string& order) { - _debug ("Setcreate accounts order : %s", order.c_str()); + _debug ("Manager: Set accounts order : %s", order.c_str()); // Set the new config - setConfig (PREFERENCES, CONFIG_ACCOUNTS_ORDER, order); + + preferences.setAccountOrder (order); } std::vector<std::string> ManagerImpl::getAccountList () @@ -3409,26 +3217,35 @@ std::vector<std::string> ManagerImpl::getAccountList () std::vector<std::string> account_order; unsigned int i; + _debug ("Manager: Get account list"); + account_order = loadAccountOrder(); AccountMap::iterator iter; // The IP2IP profile is always available, and first in the list iter = _accountMap.find (IP2IP_PROFILE); - if (iter->second != NULL) - v.push_back (iter->first.data()); + if (iter->second != NULL) { + // _debug("PUSHING BACK %s", iter->first.c_str()); + // v.push_back(iter->first.data()); + v.push_back (iter->second->getAccountID()); + } else { + _error ("Manager: could not find IP2IP profile in getAccount list"); + } // If no order has been set, load the default one // ie according to the creation date. if (account_order.size() == 0) { + _debug ("Manager: account order is empty"); iter = _accountMap.begin(); while (iter != _accountMap.end()) { if (iter->second != NULL && iter->first != IP2IP_PROFILE) { - //_debug("PUSHING BACK %s\n", iter->first.c_str()); - v.push_back (iter->first.data()); + _debug ("PUSHING BACK %s", iter->first.c_str()); + // v.push_back(iter->first.data()); + v.push_back (iter->second->getAccountID()); } iter++; @@ -3438,6 +3255,7 @@ std::vector<std::string> ManagerImpl::getAccountList () // Otherelse, load the custom one // ie according to the saved order else { + _debug ("Manager: Load account list according to preferences"); for (i = 0; i < account_order.size(); i++) { // This account has not been loaded, so we ignore it @@ -3445,7 +3263,9 @@ std::vector<std::string> ManagerImpl::getAccountList () != _accountMap.end()) { // If the account is valid if (iter->second != NULL && iter->first != IP2IP_PROFILE) { - v.push_back (iter->first.data()); + //_debug("PUSHING BACK %s", iter->first.c_str()); + // v.push_back(iter->first.data()); + v.push_back (iter->second->getAccountID()); } } } @@ -3457,150 +3277,18 @@ std::vector<std::string> ManagerImpl::getAccountList () std::map<std::string, std::string> ManagerImpl::getAccountDetails ( const AccountID& accountID) { - std::map<std::string, std::string> a; - - Account * account = _accountMap[accountID]; - - if (account == NULL) { - _debug ("Cannot getAccountDetails on a non-existing accountID %s. Defaults will be used.", accountID.c_str()); - } - - a.insert (std::pair<std::string, std::string> (ACCOUNT_ID, accountID)); - - // The IP profile does not allow to set an alias - (accountID == IP2IP_PROFILE) ? a.insert ( - std::pair<std::string, std::string> (CONFIG_ACCOUNT_ALIAS, - DIRECT_IP_CALL)) : a.insert (std::pair<std::string, - std::string> (CONFIG_ACCOUNT_ALIAS, getConfigString (accountID, - CONFIG_ACCOUNT_ALIAS))); - - a.insert (std::pair<std::string, std::string> (CONFIG_ACCOUNT_ENABLE, - getConfigString (accountID, CONFIG_ACCOUNT_ENABLE))); - a.insert (std::pair<std::string, std::string> (CONFIG_ACCOUNT_RESOLVE_ONCE, - getConfigString (accountID, CONFIG_ACCOUNT_RESOLVE_ONCE))); - a.insert (std::pair<std::string, std::string> (CONFIG_ACCOUNT_TYPE, - getConfigString (accountID, CONFIG_ACCOUNT_TYPE))); - a.insert (std::pair<std::string, std::string> (HOSTNAME, getConfigString ( - accountID, HOSTNAME))); - a.insert (std::pair<std::string, std::string> (USERNAME, getConfigString ( - accountID, USERNAME))); - a.insert (std::pair<std::string, std::string> (ROUTESET, getConfigString ( - accountID, ROUTESET))); - a.insert (std::pair<std::string, std::string> (PASSWORD, getConfigString ( - accountID, PASSWORD))); - a.insert (std::pair<std::string, std::string> (REALM, getConfigString ( - accountID, REALM))); - a.insert (std::pair<std::string, std::string> (USERAGENT, getConfigString ( - accountID, USERAGENT))); - a.insert (std::pair<std::string, std::string> (AUTHENTICATION_USERNAME, - getConfigString (accountID, AUTHENTICATION_USERNAME))); - a.insert (std::pair<std::string, std::string> (CONFIG_ACCOUNT_MAILBOX, - getConfigString (accountID, CONFIG_ACCOUNT_MAILBOX))); - a.insert (std::pair<std::string, std::string> ( - CONFIG_ACCOUNT_REGISTRATION_EXPIRE, getConfigString (accountID, - CONFIG_ACCOUNT_REGISTRATION_EXPIRE))); - a.insert (std::pair<std::string, std::string> (LOCAL_INTERFACE, - getConfigString (accountID, LOCAL_INTERFACE))); - a.insert (std::pair<std::string, std::string> (PUBLISHED_SAMEAS_LOCAL, - getConfigString (accountID, PUBLISHED_SAMEAS_LOCAL))); - a.insert (std::pair<std::string, std::string> (PUBLISHED_ADDRESS, - getConfigString (accountID, PUBLISHED_ADDRESS))); - a.insert (std::pair<std::string, std::string> (LOCAL_PORT, getConfigString ( - accountID, LOCAL_PORT))); - a.insert (std::pair<std::string, std::string> (PUBLISHED_PORT, - getConfigString (accountID, PUBLISHED_PORT))); - a.insert (std::pair<std::string, std::string> (DISPLAY_NAME, getConfigString ( - accountID, DISPLAY_NAME))); - a.insert (std::pair<std::string, std::string> (STUN_ENABLE, getConfigString ( - accountID, STUN_ENABLE))); - a.insert (std::pair<std::string, std::string> (STUN_SERVER, getConfigString ( - accountID, STUN_SERVER))); - a.insert (std::pair<std::string, std::string> (ACCOUNT_DTMF_TYPE, getConfigString ( - accountID, ACCOUNT_DTMF_TYPE))); - - RegistrationState state = Unregistered; - std::string registrationStateCode; - std::string registrationStateDescription; - - if (account != NULL) { - if (accountID == IP2IP_PROFILE) { - registrationStateCode = EMPTY_FIELD; - registrationStateDescription = "Direct IP call"; - } else { - state = account->getRegistrationState(); - int code = account->getRegistrationStateDetailed().first; - std::stringstream out; - out << code; - registrationStateCode = out.str(); - registrationStateDescription - = account->getRegistrationStateDetailed().second; - } - } - (accountID == IP2IP_PROFILE) ? a.insert ( - std::pair<std::string, std::string> (REGISTRATION_STATUS, "READY")) - : a.insert (std::pair<std::string, std::string> (REGISTRATION_STATUS, - mapStateNumberToString (state))); - - a.insert (std::pair<std::string, std::string> (REGISTRATION_STATE_CODE, - registrationStateCode)); - a.insert (std::pair<std::string, std::string> ( - REGISTRATION_STATE_DESCRIPTION, registrationStateDescription)); - a.insert (std::pair<std::string, std::string> (SRTP_KEY_EXCHANGE, - getConfigString (accountID, SRTP_KEY_EXCHANGE))); - a.insert (std::pair<std::string, std::string> (SRTP_ENABLE, getConfigString ( - accountID, SRTP_ENABLE))); - a.insert (std::pair<std::string, std::string> (SRTP_RTP_FALLBACK, - getConfigString (accountID, SRTP_RTP_FALLBACK))); - a.insert (std::pair<std::string, std::string> (ZRTP_DISPLAY_SAS, - getConfigString (accountID, ZRTP_DISPLAY_SAS))); - a.insert (std::pair<std::string, std::string> (ZRTP_DISPLAY_SAS_ONCE, - getConfigString (accountID, ZRTP_DISPLAY_SAS_ONCE))); - a.insert (std::pair<std::string, std::string> (ZRTP_HELLO_HASH, - getConfigString (accountID, ZRTP_HELLO_HASH))); - a.insert (std::pair<std::string, std::string> (ZRTP_NOT_SUPP_WARNING, - getConfigString (accountID, ZRTP_NOT_SUPP_WARNING))); - - // TLS listener is unique and parameters are modified through IP2IP_PROFILE - a.insert (std::pair<std::string, std::string> (TLS_LISTENER_PORT, - Manager::instance().getConfigString (IP2IP_PROFILE, - TLS_LISTENER_PORT))); - a.insert (std::pair<std::string, std::string> (TLS_ENABLE, - Manager::instance().getConfigString (accountID, TLS_ENABLE))); - a.insert (std::pair<std::string, std::string> (TLS_CA_LIST_FILE, - Manager::instance().getConfigString (accountID, TLS_CA_LIST_FILE))); - a.insert ( - std::pair<std::string, std::string> (TLS_CERTIFICATE_FILE, - Manager::instance().getConfigString (accountID, - TLS_CERTIFICATE_FILE))); - a.insert ( - std::pair<std::string, std::string> (TLS_PRIVATE_KEY_FILE, - Manager::instance().getConfigString (accountID, - TLS_PRIVATE_KEY_FILE))); - a.insert (std::pair<std::string, std::string> (TLS_PASSWORD, - Manager::instance().getConfigString (accountID, TLS_PASSWORD))); - a.insert (std::pair<std::string, std::string> (TLS_METHOD, - Manager::instance().getConfigString (accountID, TLS_METHOD))); - a.insert (std::pair<std::string, std::string> (TLS_CIPHERS, - Manager::instance().getConfigString (accountID, TLS_CIPHERS))); - a.insert (std::pair<std::string, std::string> (TLS_SERVER_NAME, - Manager::instance().getConfigString (accountID, TLS_SERVER_NAME))); - a.insert (std::pair<std::string, std::string> (TLS_VERIFY_SERVER, - Manager::instance().getConfigString (accountID, TLS_VERIFY_SERVER))); - a.insert (std::pair<std::string, std::string> (TLS_VERIFY_CLIENT, - Manager::instance().getConfigString (accountID, TLS_VERIFY_CLIENT))); - a.insert (std::pair<std::string, std::string> ( - TLS_REQUIRE_CLIENT_CERTIFICATE, - Manager::instance().getConfigString (accountID, - TLS_REQUIRE_CLIENT_CERTIFICATE))); - a.insert (std::pair<std::string, std::string> (TLS_NEGOTIATION_TIMEOUT_SEC, - Manager::instance().getConfigString (accountID, - TLS_NEGOTIATION_TIMEOUT_SEC))); - a.insert (std::pair<std::string, std::string> (TLS_NEGOTIATION_TIMEOUT_MSEC, - Manager::instance().getConfigString (accountID, - TLS_NEGOTIATION_TIMEOUT_MSEC))); - - return a; + _debug ("Manager: get account details %s", accountID.c_str()); + + Account * account; + + if (! (account = _accountMap[accountID])) { + _debug ("Manager: Get account details on a non-existing accountID %s. Returning default", accountID.c_str()); + // return a default map + return defaultAccount.getAccountDetails(); + } else + return account->getAccountDetails(); + } /* Transform digest to string. @@ -3652,72 +3340,13 @@ std::string ManagerImpl::computeMd5HashFromCredential ( return hashedDigest; } -void ManagerImpl::setCredential (const std::string& accountID, - const int32_t& index, const std::map<std::string, std::string>& details) +void ManagerImpl::setCredential (const std::string& accountID UNUSED, + const int32_t& index UNUSED, const std::map<std::string, std::string>& details UNUSED) { - std::map<std::string, std::string>::iterator it; - std::map<std::string, std::string> credentialInformation = details; - - std::string credentialIndex; - std::stringstream streamOut; - streamOut << index; - credentialIndex = streamOut.str(); - std::string section = "Credential" + std::string (":") + accountID - + std::string (":") + credentialIndex; - - _debug ("Setting credential in section %s", section.c_str()); - - it = credentialInformation.find (USERNAME); - std::string username; - - if (it == credentialInformation.end()) { - username = EMPTY_FIELD; - } else { - username = it->second; - } - - Manager::instance().setConfig (section, USERNAME, username); - - it = credentialInformation.find (REALM); - std::string realm; - - if (it == credentialInformation.end()) { - realm = EMPTY_FIELD; - } else { - realm = it->second; - } - - Manager::instance().setConfig (section, REALM, realm); - - it = credentialInformation.find (PASSWORD); - std::string password; - - if (it == credentialInformation.end()) { - password = EMPTY_FIELD; - } else { - password = it->second; - } - - if (getMd5CredentialHashing()) { - // TODO: Fix this. - // This is an extremly weak test in order to check - // if the password is a hashed value. This is done - // because deleteCredential() is called before this - // method. Therefore, we cannot check if the value - // is different from the one previously stored in - // the configuration file. This is to avoid to - // re-hash a hashed password. - - if (password.length() != 32) { - password = computeMd5HashFromCredential (username, password, realm); - } - } - - Manager::instance().setConfig (section, PASSWORD, password); + _debug ("Manager: set credential"); } -//TODO: tidy this up. Make a macro or inline // method to reduce the if/else mess. // Even better, switch to XML ! @@ -3725,218 +3354,23 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::map<std::string, std::string>& details) { - std::map<std::string, std::string> map_cpy; - std::map<std::string, std::string>::iterator iter; - - // Work on a copy - map_cpy = details; - - // Get the account type - std::string accountType; - find_in_map (CONFIG_ACCOUNT_TYPE, accountType) - - std::string alias; - std::string type; - std::string hostname; - std::string username; - std::string password; - std::string mailbox; - std::string accountEnable; - - - // Account setting common to SIP and IAX - find_in_map (CONFIG_ACCOUNT_ALIAS, alias) - find_in_map (CONFIG_ACCOUNT_TYPE, type) - find_in_map (HOSTNAME, hostname) - find_in_map (USERNAME, username) - find_in_map (PASSWORD, password) - find_in_map (CONFIG_ACCOUNT_MAILBOX, mailbox); - find_in_map (CONFIG_ACCOUNT_ENABLE, accountEnable); - - setConfig (accountID, CONFIG_ACCOUNT_ALIAS, alias); - setConfig (accountID, CONFIG_ACCOUNT_TYPE, type); - setConfig (accountID, HOSTNAME, hostname); - setConfig (accountID, USERNAME, username); - setConfig (accountID, PASSWORD, password); - setConfig (accountID, CONFIG_ACCOUNT_MAILBOX, mailbox); - setConfig (accountID, CONFIG_ACCOUNT_ENABLE, accountEnable); - - // SIP specific account settings - if (accountType == "SIP") { - - std::string ua_name; - std::string realm; - std::string routeset; - std::string authenticationName; - - std::string resolveOnce; - std::string registrationExpire; - - std::string displayName; - std::string localInterface; - std::string publishedSameasLocal; - std::string localAddress; - std::string publishedAddress; - std::string localPort; - std::string publishedPort; - std::string stunEnable; - std::string stunServer; - std::string dtmfType; - std::string srtpEnable; - std::string srtpRtpFallback; - std::string zrtpDisplaySas; - std::string zrtpDisplaySasOnce; - std::string zrtpNotSuppWarning; - std::string zrtpHelloHash; - std::string srtpKeyExchange; - - std::string tlsListenerPort; - std::string tlsEnable; - std::string tlsCaListFile; - std::string tlsCertificateFile; - std::string tlsPrivateKeyFile; - std::string tlsPassword; - std::string tlsMethod; - std::string tlsCiphers; - std::string tlsServerName; - std::string tlsVerifyServer; - std::string tlsVerifyClient; - std::string tlsRequireClientCertificate; - std::string tlsNegotiationTimeoutSec; - std::string tlsNegotiationTimeoutMsec; - - // general sip settings - find_in_map (DISPLAY_NAME, displayName) - find_in_map (ROUTESET, routeset) - find_in_map (LOCAL_INTERFACE, localInterface) - find_in_map (PUBLISHED_SAMEAS_LOCAL, publishedSameasLocal) - find_in_map (PUBLISHED_ADDRESS, publishedAddress) - find_in_map (LOCAL_PORT, localPort) - find_in_map (PUBLISHED_PORT, publishedPort) - find_in_map (STUN_ENABLE, stunEnable) - find_in_map (STUN_SERVER, stunServer) - find_in_map (ACCOUNT_DTMF_TYPE, dtmfType) - find_in_map (CONFIG_ACCOUNT_RESOLVE_ONCE, resolveOnce) - find_in_map (CONFIG_ACCOUNT_REGISTRATION_EXPIRE, registrationExpire) - - setConfig (accountID, DISPLAY_NAME, displayName); - setConfig (accountID, ROUTESET, routeset); - setConfig (accountID, LOCAL_INTERFACE, localInterface); - setConfig (accountID, PUBLISHED_SAMEAS_LOCAL, publishedSameasLocal); - setConfig (accountID, PUBLISHED_ADDRESS, publishedAddress); - setConfig (accountID, LOCAL_PORT, localPort); - setConfig (accountID, PUBLISHED_PORT, publishedPort); - setConfig (accountID, STUN_ENABLE, stunEnable); - setConfig (accountID, STUN_SERVER, stunServer); - setConfig (accountID, ACCOUNT_DTMF_TYPE, dtmfType); - setConfig (accountID, CONFIG_ACCOUNT_RESOLVE_ONCE, resolveOnce); - setConfig (accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE, registrationExpire); - - // sip credential - find_in_map (REALM, realm) - find_in_map (AUTHENTICATION_USERNAME, authenticationName) - find_in_map (USERAGENT, ua_name) - - setConfig (accountID, REALM, realm); - setConfig (accountID, USERAGENT, ua_name); - setConfig (accountID, AUTHENTICATION_USERNAME, authenticationName); - - // srtp settings - find_in_map (SRTP_ENABLE, srtpEnable) - find_in_map (SRTP_RTP_FALLBACK, srtpRtpFallback) - find_in_map (ZRTP_DISPLAY_SAS, zrtpDisplaySas) - find_in_map (ZRTP_DISPLAY_SAS_ONCE, zrtpDisplaySasOnce) - find_in_map (ZRTP_NOT_SUPP_WARNING, zrtpNotSuppWarning) - find_in_map (ZRTP_HELLO_HASH, zrtpHelloHash) - find_in_map (SRTP_KEY_EXCHANGE, srtpKeyExchange) - - setConfig (accountID, SRTP_ENABLE, srtpEnable); - setConfig (accountID, SRTP_RTP_FALLBACK, srtpRtpFallback); - setConfig (accountID, ZRTP_DISPLAY_SAS, zrtpDisplaySas); - setConfig (accountID, ZRTP_DISPLAY_SAS_ONCE, zrtpDisplaySasOnce); - setConfig (accountID, ZRTP_NOT_SUPP_WARNING, zrtpNotSuppWarning); - setConfig (accountID, ZRTP_HELLO_HASH, zrtpHelloHash); - setConfig (accountID, SRTP_KEY_EXCHANGE, srtpKeyExchange); - - // TLS settings - // The TLS listener is unique and globally defined through IP2IP_PROFILE - if (accountID == IP2IP_PROFILE) { - find_in_map (TLS_LISTENER_PORT, tlsListenerPort) - } - - find_in_map (TLS_ENABLE, tlsEnable) - find_in_map (TLS_CA_LIST_FILE, tlsCaListFile) - find_in_map (TLS_CERTIFICATE_FILE, tlsCertificateFile) - find_in_map (TLS_PRIVATE_KEY_FILE, tlsPrivateKeyFile) - find_in_map (TLS_PASSWORD, tlsPassword) - find_in_map (TLS_METHOD, tlsMethod) - find_in_map (TLS_CIPHERS, tlsCiphers) - find_in_map (TLS_SERVER_NAME, tlsServerName) - find_in_map (TLS_VERIFY_SERVER, tlsVerifyServer) - find_in_map (TLS_VERIFY_CLIENT, tlsVerifyClient) - find_in_map (TLS_REQUIRE_CLIENT_CERTIFICATE, tlsRequireClientCertificate) - find_in_map (TLS_NEGOTIATION_TIMEOUT_SEC, tlsNegotiationTimeoutSec) - find_in_map (TLS_NEGOTIATION_TIMEOUT_MSEC, tlsNegotiationTimeoutMsec) - - - // The TLS listener is unique and globally defined through IP2IP_PROFILE - if (accountID == IP2IP_PROFILE) { - setConfig (accountID, TLS_LISTENER_PORT, tlsListenerPort); - } + _debug ("Manager: Set account details %s", accountID.c_str()); - setConfig (accountID, TLS_ENABLE, tlsEnable); - setConfig (accountID, TLS_CA_LIST_FILE, tlsCaListFile); - setConfig (accountID, TLS_CERTIFICATE_FILE, tlsCertificateFile); - setConfig (accountID, TLS_PRIVATE_KEY_FILE, tlsPrivateKeyFile); - setConfig (accountID, TLS_PASSWORD, tlsPassword); - setConfig (accountID, TLS_METHOD, tlsMethod); - setConfig (accountID, TLS_CIPHERS, tlsCiphers); - setConfig (accountID, TLS_SERVER_NAME, tlsServerName); - setConfig (accountID, TLS_VERIFY_SERVER, tlsVerifyServer); - setConfig (accountID, TLS_VERIFY_CLIENT, tlsVerifyClient); - setConfig (accountID, TLS_REQUIRE_CLIENT_CERTIFICATE, tlsRequireClientCertificate); - setConfig (accountID, TLS_NEGOTIATION_TIMEOUT_SEC, tlsNegotiationTimeoutSec); - setConfig (accountID, TLS_NEGOTIATION_TIMEOUT_MSEC,tlsNegotiationTimeoutMsec); - - if (!getMd5CredentialHashing()) { - setConfig (accountID, PASSWORD, password); - } else { - // Make sure not to re-hash the password field if - // it is already saved as a MD5 Hash. - // TODO: This test is weak. Fix this. - if ( (password.compare (getConfigString (accountID, PASSWORD)) != 0)) { - _debug ("Password sent and password from config are different. Re-hashing"); - std::string hash; - - if (authenticationName.empty()) { - hash = computeMd5HashFromCredential (username, password, realm); - } else { - hash = computeMd5HashFromCredential (authenticationName, - password, realm); - } - - setConfig (accountID, PASSWORD, hash); - } - } + Account* account; + if (! (account = getAccount (accountID))) { + _warn ("Manager: Cannot setAccountDetails on a non-existing accountID %s.", accountID.c_str()); + return; } - saveConfig(); + account->setAccountDetails (details); - Account * acc = NULL; - acc = getAccount (accountID); - - if (acc != NULL) { - acc->loadConfig(); + saveConfig(); - if (acc->isEnabled()) { - acc->registerVoIPLink(); - } else { - acc->unregisterVoIPLink(); - } - } else { - _debug ("ManagerImpl::setAccountDetails: account is NULL"); - } + if (account->isEnabled()) + account->registerVoIPLink(); + else + account->unregisterVoIPLink(); // Update account details to the client side if (_dbus) @@ -3960,7 +3394,7 @@ std::string ManagerImpl::addAccount ( // Get the type accountType = (*details.find (CONFIG_ACCOUNT_TYPE)).second; - _debug ("%s", newAccountID.c_str()); + _debug ("Manager: Adding account %s", newAccountID.c_str()); /** @todo Verify the uniqueness, in case a program adds accounts, two in a row. */ @@ -3972,24 +3406,35 @@ std::string ManagerImpl::addAccount ( newAccount = AccountCreator::createAccount (AccountCreator::IAX_ACCOUNT, newAccountID); } else { - _debug ("Unknown %s param when calling addAccount(): %s", CONFIG_ACCOUNT_TYPE, accountType.c_str()); + _error ("Unknown %s param when calling addAccount(): %s", CONFIG_ACCOUNT_TYPE, accountType.c_str()); return ""; } _accountMap[newAccountID] = newAccount; - setAccountDetails (accountID.str(), details); + newAccount->setAccountDetails (details); // Add the newly created account in the account order list - account_list = getConfigString (PREFERENCES, CONFIG_ACCOUNTS_ORDER); + account_list = preferences.getAccountOrder(); if (account_list != "") { newAccountID += "/"; // Prepend the new account account_list.insert (0, newAccountID); - setConfig (PREFERENCES, CONFIG_ACCOUNTS_ORDER, account_list); + + preferences.setAccountOrder (account_list); + } else { + newAccountID += "/"; + account_list = newAccountID; + preferences.setAccountOrder (account_list); } + _debug ("AccountMap: %s", account_list.c_str()); + + newAccount->setVoIPLink(); + + newAccount->registerVoIPLink(); + saveConfig(); if (_dbus) @@ -4000,23 +3445,21 @@ std::string ManagerImpl::addAccount ( void ManagerImpl::deleteAllCredential (const AccountID& accountID) { - int numberOfCredential = getConfigInt (accountID, CONFIG_CREDENTIAL_NUMBER); - int i; + _debug ("Manager: delete all credential"); - for (i = 0; i < numberOfCredential; i++) { - std::string credentialIndex; - std::stringstream streamOut; - streamOut << i; - credentialIndex = streamOut.str(); - std::string section = "Credential" + std::string (":") + accountID - + std::string (":") + credentialIndex; + Account *account = getAccount (accountID); - _config.removeSection (section); - } + if (!account) + return; + + if (account->getType() != "SIP") + return; + + SIPAccount *sipaccount = (SIPAccount *) account; if (accountID.empty() == false) { - setConfig (accountID, CONFIG_CREDENTIAL_NUMBER, 0); + sipaccount->setCredentialCount (0); } } @@ -4108,98 +3551,167 @@ std::vector<std::string> ManagerImpl::loadAccountOrder (void) std::string account_list; std::vector<std::string> account_vect; - account_list = getConfigString (PREFERENCES, CONFIG_ACCOUNTS_ORDER); + account_list = preferences.getAccountOrder(); + + _debug ("Manager: Load sccount order %s", account_list.c_str()); + return unserialize (account_list); } -short ManagerImpl::loadAccountMap () +short ManagerImpl::buildConfiguration () { - _debug ("Loading account map"); + _debug ("Manager: Loading account map"); - short nbAccount = 0; - TokenList sections = _config.getSections(); - std::string accountType; - Account *tmpAccount = 0; - std::vector<std::string> account_order; + loadIptoipProfile(); - TokenList::iterator iter = sections.begin(); + int nbAccount = loadAccountMap(); - // Those calls that are placed to an uri that cannot be - // associated to an account are using that special account. - // An account, that is not account, in the sense of - // registration. This is useful since the Account object - // provides a handful of method that simplifies URI creation - // and loading of various settings. - _directIpAccount = AccountCreator::createAccount ( - AccountCreator::SIP_DIRECT_IP_ACCOUNT, ""); + return nbAccount; +} + +void ManagerImpl::loadIptoipProfile() +{ + + _debug ("Manager: Create default \"account\" (used as default UDP transport)"); - _debug ("Create default \"account\" (used as default UDP transport)"); + // build a default IP2IP account with default parameters + _directIpAccount = AccountCreator::createAccount (AccountCreator::SIP_DIRECT_IP_ACCOUNT, ""); + _accountMap[IP2IP_PROFILE] = _directIpAccount; if (_directIpAccount == NULL) { + _error ("Manager: Failed to create default \"account\""); + return; + } - _debug ("Failed to create default \"account\""); - } else { + // If configuration file parsed, load saved preferences + if (_setupLoaded) { - _accountMap[IP2IP_PROFILE] = _directIpAccount; + _debug ("Manager: Loading IP2IP profile preferences from config"); - // Force IP2IP settings to be loaded to be loaded - // No registration in the sense of the REGISTER method is performed. - _directIpAccount->registerVoIPLink(); + Conf::SequenceNode *seq = parser->getAccountSequence(); - // SIPVoIPlink is used as a singleton, it is the first call to instance here - // The SIP library initialization is done in the SIPVoIPLink constructor - // We need the IP2IP settings to be loaded at this time as they are used - // for default sip transport + Conf::Sequence::iterator iterIP2IP = seq->getSequence()->begin(); + Conf::Key accID ("id"); - // _directIpAccount->setVoIPLink(SIPVoIPLink::instance ("")); - _directIpAccount->setVoIPLink(); + // Iterate over every account maps + while (iterIP2IP != seq->getSequence()->end()) { - } + Conf::MappingNode *map = (Conf::MappingNode *) (*iterIP2IP); - // initialize other accounts - while (iter != sections.end()) { - // Check if it starts with "Account:" (SIP and IAX pour le moment) - if ( (int) (iter->find ("Account:")) != 0) { - iter++; - continue; - } + // Get the account id + Conf::ScalarNode * val = (Conf::ScalarNode *) (map->getValue (accID)); + Conf::Value accountid = val->getValue(); - accountType = getConfigString (*iter, CONFIG_ACCOUNT_TYPE); + // if ID is IP2IP, unserialize + if (accountid == "IP2IP") { - if (accountType == "SIP") { - tmpAccount = AccountCreator::createAccount ( - AccountCreator::SIP_ACCOUNT, *iter); - } + try { + _directIpAccount->unserialize (map); + } catch (SipAccountException &e) { + _error ("Manager: %s", e.what()); + } - else if (accountType == "IAX") { - tmpAccount = AccountCreator::createAccount ( - AccountCreator::IAX_ACCOUNT, *iter); + break; + } + + iterIP2IP++; } + } + + // Force IP2IP settings to be loaded to be loaded + // No registration in the sense of the REGISTER method is performed. + _directIpAccount->registerVoIPLink(); + + // SIPVoIPlink is used as a singleton, it is the first call to instance here + // The SIP library initialization is done in the SIPVoIPLink constructor + // We need the IP2IP settings to be loaded at this time as they are used + // for default sip transport + + // _directIpAccount->setVoIPLink(SIPVoIPLink::instance ("")); + _directIpAccount->setVoIPLink(); + +} + +short ManagerImpl::loadAccountMap() +{ + + _debug ("Manager: Load account map"); + + // Conf::YamlParser *parser; + int nbAccount = 0; + + if (!_setupLoaded) + return 0; + + // build preferences + preferences.unserialize ( (Conf::MappingNode *) (parser->getPreferenceSequence())); + voipPreferences.unserialize ( (Conf::MappingNode *) (parser->getVoipPreferenceSequence())); + addressbookPreference.unserialize ( (Conf::MappingNode *) (parser->getAddressbookSequence())); + hookPreference.unserialize ( (Conf::MappingNode *) (parser->getHookSequence())); + audioPreference.unserialize ( (Conf::MappingNode *) (parser->getAudioSequence())); + shortcutPreferences.unserialize ( (Conf::MappingNode *) (parser->getShortcutSequence())); + + Conf::SequenceNode *seq = parser->getAccountSequence(); + + // Each element in sequence is a new account to create + Conf::Sequence::iterator iterSeq = seq->getSequence()->begin(); + + Conf::Key accTypeKey ("type"); + Conf::Key accID ("id"); - else { - _error ("Unknown %s param in config file (%s)", CONFIG_ACCOUNT_TYPE, accountType.c_str()); + while (iterSeq != seq->getSequence()->end()) { + + Account *tmpAccount = NULL; + Conf::MappingNode *map = (Conf::MappingNode *) (*iterSeq); + + Conf::ScalarNode * val = (Conf::ScalarNode *) (map->getValue (accTypeKey)); + Conf::Value accountType = val->getValue(); + + val = (Conf::ScalarNode *) (map->getValue (accID)); + Conf::Value accountid = val->getValue(); + + if (accountType == "SIP" && accountid != "IP2IP") { + _debug ("Manager: Create SIP account: %s", accountid.c_str()); + tmpAccount = AccountCreator::createAccount (AccountCreator::SIP_ACCOUNT, accountid); + } else if (accountType == "IAX" && accountid != "IP2IP") { + _debug ("Manager: Create IAX account: %s", accountid.c_str()); + tmpAccount = AccountCreator::createAccount (AccountCreator::IAX_ACCOUNT, accountid); } + if (tmpAccount != NULL) { - _debug ("Loading account %s ", iter->c_str()); - _accountMap[iter->c_str() ] = tmpAccount; - // tmpAccount->setVoIPLink(SIPVoIPLink::instance ("")); + + try { + tmpAccount->unserialize (map); + } catch (SipAccountException &e) { + _error ("Manager: %s", e.what()); + } + + _accountMap[accountid] = tmpAccount; + _debug ("Manager: Loading account %s (size %d)", accountid.c_str(), _accountMap.size()); + tmpAccount->setVoIPLink(); nbAccount++; } - iter++; + iterSeq++; } - _debug ("nb account loaded %i \n", nbAccount); + try { + delete parser; + } catch (Conf::YamlParserException &e) { + _error ("Manager: %s", e.what()); + } + + parser = NULL; return nbAccount; + } void ManagerImpl::unloadAccountMap () { - AccountMap::iterator iter = _accountMap.begin(); while (iter != _accountMap.end()) { @@ -4305,22 +3817,12 @@ std::map<std::string, int32_t> ManagerImpl::getAddressbookSettings () std::map<std::string, int32_t> settings; - settings.insert (std::pair<std::string, int32_t> ("ADDRESSBOOK_ENABLE", - getConfigInt (ADDRESSBOOK, ADDRESSBOOK_ENABLE))); - settings.insert (std::pair<std::string, int32_t> ("ADDRESSBOOK_MAX_RESULTS", - getConfigInt (ADDRESSBOOK, ADDRESSBOOK_MAX_RESULTS))); - settings.insert (std::pair<std::string, int32_t> ( - "ADDRESSBOOK_DISPLAY_CONTACT_PHOTO", getConfigInt (ADDRESSBOOK, - ADDRESSBOOK_DISPLAY_CONTACT_PHOTO))); - settings.insert (std::pair<std::string, int32_t> ( - "ADDRESSBOOK_DISPLAY_PHONE_BUSINESS", getConfigInt (ADDRESSBOOK, - ADDRESSBOOK_DISPLAY_PHONE_BUSINESS))); - settings.insert (std::pair<std::string, int32_t> ( - "ADDRESSBOOK_DISPLAY_PHONE_HOME", getConfigInt (ADDRESSBOOK, - ADDRESSBOOK_DISPLAY_PHONE_HOME))); - settings.insert (std::pair<std::string, int32_t> ( - "ADDRESSBOOK_DISPLAY_PHONE_MOBILE", getConfigInt (ADDRESSBOOK, - ADDRESSBOOK_DISPLAY_PHONE_MOBILE))); + settings.insert (std::pair<std::string, int32_t> ("ADDRESSBOOK_ENABLE", addressbookPreference.getEnabled() ? 1 : 0)); + settings.insert (std::pair<std::string, int32_t> ("ADDRESSBOOK_MAX_RESULTS", addressbookPreference.getMaxResults())); + settings.insert (std::pair<std::string, int32_t> ("ADDRESSBOOK_DISPLAY_CONTACT_PHOTO", addressbookPreference.getPhoto() ? 1 : 0)); + settings.insert (std::pair<std::string, int32_t> ("ADDRESSBOOK_DISPLAY_PHONE_BUSINESS", addressbookPreference.getBusiness() ? 1 : 0)); + settings.insert (std::pair<std::string, int32_t> ("ADDRESSBOOK_DISPLAY_PHONE_HOME", addressbookPreference.getHome() ? 1 : 0)); + settings.insert (std::pair<std::string, int32_t> ("ADDRESSBOOK_DISPLAY_PHONE_MOBILE", addressbookPreference.getMobile() ? 1 : 0)); return settings; } @@ -4329,18 +3831,13 @@ void ManagerImpl::setAddressbookSettings ( const std::map<std::string, int32_t>& settings) { - setConfig (ADDRESSBOOK, ADDRESSBOOK_ENABLE, (*settings.find ( - "ADDRESSBOOK_ENABLE")).second); - setConfig (ADDRESSBOOK, ADDRESSBOOK_MAX_RESULTS, (*settings.find ( - "ADDRESSBOOK_MAX_RESULTS")).second); - setConfig (ADDRESSBOOK, ADDRESSBOOK_DISPLAY_CONTACT_PHOTO, (*settings.find ( - "ADDRESSBOOK_DISPLAY_CONTACT_PHOTO")).second); - setConfig (ADDRESSBOOK, ADDRESSBOOK_DISPLAY_PHONE_BUSINESS, (*settings.find ( - "ADDRESSBOOK_DISPLAY_PHONE_BUSINESS")).second); - setConfig (ADDRESSBOOK, ADDRESSBOOK_DISPLAY_PHONE_HOME, (*settings.find ( - "ADDRESSBOOK_DISPLAY_PHONE_HOME")).second); - setConfig (ADDRESSBOOK, ADDRESSBOOK_DISPLAY_PHONE_MOBILE, (*settings.find ( - "ADDRESSBOOK_DISPLAY_PHONE_MOBILE")).second); + + addressbookPreference.setEnabled ( (settings.find ("ADDRESSBOOK_ENABLE")->second == 1) ? true : false); + addressbookPreference.setMaxResults (settings.find ("ADDRESSBOOK_MAX_RESULTS")->second); + addressbookPreference.setPhoto ( (settings.find ("ADDRESSBOOK_DISPLAY_CONTACT_PHOTO")->second == 1) ? true : false); + addressbookPreference.setBusiness ( (settings.find ("ADDRESSBOOK_DISPLAY_PHONE_BUSINESS")->second == 1) ? true : false); + addressbookPreference.setHone ( (settings.find ("ADDRESSBOOK_DISPLAY_PHONE_HOME")->second == 1) ? true : false); + addressbookPreference.setMobile ( (settings.find ("ADDRESSBOOK_DISPLAY_PHONE_MOBILE")->second == 1) ? true : false); // Write it to the configuration file saveConfig(); @@ -4350,13 +3847,14 @@ void ManagerImpl::setAddressbookList (const std::vector<std::string>& list) { std::string s = serialize (list); - setConfig (ADDRESSBOOK, ADDRESSBOOK_LIST, s); + addressbookPreference.setList (s); + } std::vector<std::string> ManagerImpl::getAddressbookList (void) { - std::string s = getConfigString (ADDRESSBOOK, ADDRESSBOOK_LIST); + std::string s = addressbookPreference.getList(); return unserialize (s); } @@ -4365,40 +3863,26 @@ std::map<std::string, std::string> ManagerImpl::getHookSettings () std::map<std::string, std::string> settings; - settings.insert (std::pair<std::string, std::string> ("URLHOOK_SIP_FIELD", - getConfigString (HOOKS, URLHOOK_SIP_FIELD))); - settings.insert (std::pair<std::string, std::string> ("URLHOOK_COMMAND", - getConfigString (HOOKS, URLHOOK_COMMAND))); - settings.insert (std::pair<std::string, std::string> ("URLHOOK_SIP_ENABLED", - getConfigString (HOOKS, URLHOOK_SIP_ENABLED))); - settings.insert (std::pair<std::string, std::string> ("URLHOOK_IAX2_ENABLED", - getConfigString (HOOKS, URLHOOK_IAX2_ENABLED))); - settings.insert (std::pair<std::string, std::string> ( - "PHONE_NUMBER_HOOK_ENABLED", getConfigString (HOOKS, - PHONE_NUMBER_HOOK_ENABLED))); - settings.insert (std::pair<std::string, std::string> ( - "PHONE_NUMBER_HOOK_ADD_PREFIX", getConfigString (HOOKS, - PHONE_NUMBER_HOOK_ADD_PREFIX))); + + settings.insert (std::pair<std::string, std::string> ("URLHOOK_IAX2_ENABLED", hookPreference.getIax2Enabled() ? "true" : "false")); + settings.insert (std::pair<std::string, std::string> ("PHONE_NUMBER_HOOK_ADD_PREFIX", hookPreference.getNumberAddPrefix())); + settings.insert (std::pair<std::string, std::string> ("PHONE_NUMBER_HOOK_ENABLED", hookPreference.getNumberEnabled() ? "true" : "false")); + settings.insert (std::pair<std::string, std::string> ("URLHOOK_SIP_ENABLED", hookPreference.getSipEnabled() ? "true" : "false")); + settings.insert (std::pair<std::string, std::string> ("URLHOOK_COMMAND", hookPreference.getUrlCommand())); + settings.insert (std::pair<std::string, std::string> ("URLHOOK_SIP_FIELD", hookPreference.getUrlSipField())); return settings; } -void ManagerImpl::setHookSettings ( - const std::map<std::string, std::string>& settings) +void ManagerImpl::setHookSettings (const std::map<std::string, std::string>& settings) { - setConfig (HOOKS, URLHOOK_SIP_FIELD, - (*settings.find ("URLHOOK_SIP_FIELD")).second); - setConfig (HOOKS, URLHOOK_COMMAND, - (*settings.find ("URLHOOK_COMMAND")).second); - setConfig (HOOKS, URLHOOK_SIP_ENABLED, - (*settings.find ("URLHOOK_SIP_ENABLED")).second); - setConfig (HOOKS, URLHOOK_IAX2_ENABLED, (*settings.find ( - "URLHOOK_IAX2_ENABLED")).second); - setConfig (HOOKS, PHONE_NUMBER_HOOK_ENABLED, (*settings.find ( - "PHONE_NUMBER_HOOK_ENABLED")).second); - setConfig (HOOKS, PHONE_NUMBER_HOOK_ADD_PREFIX, (*settings.find ( - "PHONE_NUMBER_HOOK_ADD_PREFIX")).second); + hookPreference.setIax2Enabled ( (settings.find ("URLHOOK_IAX2_ENABLED")->second == "true") ? true : false); + hookPreference.setNumberAddPrefix (settings.find ("PHONE_NUMBER_HOOK_ADD_PREFIX")->second); + hookPreference.setNumberEnabled ( (settings.find ("PHONE_NUMBER_HOOK_ENABLED")->second == "true") ? true : false); + hookPreference.setSipEnabled ( (settings.find ("URLHOOK_SIP_ENABLED")->second == "true") ? true : false); + hookPreference.setUrlCommand (settings.find ("URLHOOK_COMMAND")->second); + hookPreference.setUrlSipField (settings.find ("URLHOOK_SIP_FIELD")->second); // Write it to the configuration file saveConfig(); @@ -4510,8 +3994,8 @@ std::map<std::string, std::string> ManagerImpl::send_history_to_client (void) void ManagerImpl::receive_history_from_client (std::map<std::string, std::string> history) { - _history->set_serialized_history (history, Manager::instance().getConfigInt ( - PREFERENCES, CONFIG_HISTORY_LIMIT)); + + _history->set_serialized_history (history, preferences.getHistoryLimit());; _history->save_history(); } @@ -4597,3 +4081,4 @@ std::vector<std::string> ManagerImpl::getParticipantList ( return v; } + diff --git a/sflphone-common/src/managerimpl.h b/sflphone-common/src/managerimpl.h index 277a9ececcd123e5ec65a91a38f5533ec3618b4d..5f69d1e191bf27d67476cf6aaa8acbc2d8716853 100644 --- a/sflphone-common/src/managerimpl.h +++ b/sflphone-common/src/managerimpl.h @@ -50,11 +50,14 @@ #include "numbercleaner.h" #include "audio/sound/tonelist.h" // for Tone::TONEID declaration -#include "audio/sound/audiofile.h" // AudioFile class contained by value here +#include "audio/sound/audiofile.h" #include "audio/sound/dtmf.h" // DTMF class contained by value here #include "audio/codecs/codecDescriptor.h" // CodecDescriptor class contained by value here #include "audio/mainbuffer.h" +#include "yamlemitter.h" +#include "yamlparser.h" +#include "preferences.h" class AudioLayer; class GuiFramework; @@ -84,14 +87,14 @@ typedef std::set<CallID> CallIDSet; /** To send multiple string */ typedef std::list<std::string> TokenList; -/** To store conference objects by call ids +/** To store conference objects by call ids used to retreive the conference according to a call */ typedef std::map<CallID, Conference*> ConferenceCallMap; /** To store conference objects by conference ids */ typedef std::map<CallID, Conference*> ConferenceMap; -static CallID default_conf = "conf"; +static CallID default_conf = "conf"; static char * mapStateToChar[] = { (char*) "UNREGISTERED", @@ -101,1252 +104,1306 @@ static char * mapStateToChar[] = { (char*) "ERRORAUTH", (char*) "ERRORNETWORK", (char*) "ERRORHOST", - (char*) "ERROREXISTSTUN", - (char*) "ERRORCONFSTUN" + (char*) "ERROREXISTSTUN", + (char*) "ERRORCONFSTUN" }; /** Manager (controller) of sflphone daemon */ -class ManagerImpl { - public: - ManagerImpl (void); - ~ManagerImpl (void); - - /** - * Initialisation of thread (sound) and map. - * Init a new VoIPLink, audio codec and audio driver - */ - void init (void); - - /** - * Terminate all thread (sound, link) and unload AccountMap - */ - void terminate (void); - - /** - * Set user interface manager. - * @param man The DBUS interface implementation - */ - void setDBusManager (DBusManagerImpl* man) { _dbus = man; } - - /** - * Accessor to audiodriver. - * it's multi-thread and use mutex internally - * @return AudioLayer* The audio layer object - */ - AudioLayer* getAudioDriver(void) const { return _audiodriver; } - - /** - * Get a descriptor map of codec available - * @return CodecDescriptor The internal codec map - */ - CodecDescriptor& getCodecDescriptorMap(void) {return _codecDescriptorMap;} - - /** - * Functions which occur with a user's action - * Place a new call - * @param accountId The account to make tha call with - * @param id The call identifier - * @param to The recipient of the call - * @return bool true on success - * false otherwise - */ - bool outgoingCall(const AccountID& accountId, const CallID& id, const std::string& to); - - /** - * Functions which occur with a user's action - * Answer the call - * @param id The call identifier - */ - bool answerCall(const CallID& id); - - /** - * Functions which occur with a user's action - * Hangup the call - * @param id The call identifier - */ - bool hangupCall(const CallID& id); - - - /** - * Functions which occur with a user's action - * Hangup the conference (hangup every participants) - * @param id The call identifier - */ - bool hangupConference(const ConfID& id); - - /** - * Functions which occur with a user's action - * Cancel the call - * @param id The call identifier - */ - bool cancelCall(const CallID& id); - - /** - * Functions which occur with a user's action - * Put the call on hold - * @param id The call identifier - */ - bool onHoldCall(const CallID& id); - - /** - * Functions which occur with a user's action - * Put the call off hold - * @param id The call identifier - */ - bool offHoldCall(const CallID& id); - - /** - * Functions which occur with a user's action - * Transfer the call - * @param id The call identifier - * @param to The recipient of the transfer - */ - bool transferCall(const CallID& id, const std::string& to); - - /** - * Notify the client the transfer is successful - */ - void transferSucceded(); - - /** - * Notify the client that the transfer failed - */ - void transferFailed(); - - /** - * Functions which occur with a user's action - * Refuse the call - * @param id The call identifier - */ - bool refuseCall(const CallID& id); - - /** - * Create a new conference given two participant - * @param the first participant ID - * @param the second participant ID - */ - Conference* createConference(const CallID& id1, const CallID& id2); - - /** - * Delete this conference - * @param the conference ID - */ - void removeConference(const CallID& conference_id); - - /** - * Return the conference id for which this call is attached - * @ param the call id - */ - Conference* getConferenceFromCallID(const CallID& call_id); - - /** - * Hold every participant to a conference - * @param the conference id - */ - void holdConference(const CallID& conferece_id); - - /** - * Unhold all conference participants - * @param the conference id - */ - void unHoldConference(const CallID& conference_id); - - /** - * Test if this id is a conference (usefull to test current call) - * @param the call id - */ - bool isConference(const CallID& call_id); - - /** - * Test if a call id particips to this conference - * @param the call id - */ - bool participToConference(const CallID& call_id); - - /** - * Add a participant to a conference - * @param the call id - * @param the conference id - */ - void addParticipant(const CallID& call_id, const CallID& conference_id); - - /** - * Bind the main participant to a conference (mainly called on a double click action) - * @param the conference id - */ - void addMainParticipant(const CallID& conference_id); - - /** - * Join two participants to create a conference - * @param the fist call id - * @param the second call id - */ - void joinParticipant(const CallID& call_id1, const CallID& call_id2); - - /** - * Detach a participant from a conference, put the call on hold, do not hangup it - * @param call id - * @param the current call id - */ - void detachParticipant(const CallID& call_id, const CallID& current_call_id); - - /** - * Remove the conference participant from a conference - * @param call id - */ - void removeParticipant(const CallID& call_id); - - /** - * Process remaining participant given a conference and the current call id. - * Mainly called when a participant is detached or hagned up - * @param current call id - * @param conference pointer - */ - void processRemainingParticipant(CallID current_call_id, Conference *conf); - - /** - * Join two conference together into one unique conference - */ - void joinConference(const CallID& conf_id1, const CallID& conf_id2); - - void addStream(const CallID& call_id); - - void removeStream(const CallID& call_id); - - /** - * Save config to file - * @return true on success - * false otherwise - */ - bool saveConfig (void); - - /** - * Send registration to all enabled accounts - * @return 0 on registration success - * 1 otherelse - */ - int initRegisterAccounts(); - - /** - * @return true if we tried to register once - */ - bool _hasTriedToRegister; - - /** - * Handle choice of the DTMF-send-way - * @param id: callid of the line. - * @param code: pressed key. - */ - bool sendDtmf(const CallID& id, char code); - - /** - * Play the dtmf-associated sound - * @param code The pressed key - */ - bool playDtmf (char code); - - /** - * Play a ringtone - * @return bool True on success - * false otherwise - */ - bool playTone (); - - /** - * Play a special ringtone ( BUSY ) if there's at least one message on the voice mail - * @return bool True on success - * false otherwise - */ - bool playToneWithMessage (); - - /** - * Acts on the audio streams and audio files - */ - void stopTone (void); - - /** - * When receiving a new incoming call, add it to the callaccount map - * and notify user - * @param call A call pointer - * @param accountId an account id - * @return bool True if the call was added correctly - */ - bool incomingCall(Call* call, const AccountID& accountId); - - /** - * Notify the user that the recipient of the call has answered and the put the - * call in Current state - * @param id The call identifier - */ - void peerAnsweredCall(const CallID& id); - - /** - * Rings back because the outgoing call is ringing and the put the - * call in Ringing state - * @param id The call identifier - */ - void peerRingingCall(const CallID& id); - - /** - * Put the call in Hungup state, remove the call from the list - * @param id The call identifier - */ - void peerHungupCall(const CallID& id); - - /** - * Notify the client with an incoming message - * @param accountId The account identifier - * @param message The content of the message - */ - void incomingMessage(const CallID& callId, const std::string& from, const std::string& message); - - /** - * Notify the client he has voice mails - * @param accountId The account identifier - * @param nb_msg The number of messages - */ - void startVoiceMessageNotification(const AccountID& accountId, int nb_msg); - - /** - * Notify the client through DBus that registration state has been updated - */ - void connectionStatusNotification(void); - - /** - * ConfigurationManager - Send registration request - * @param accountId The account to register/unregister - * @param enable The flag for the type of registration - * 0 for unregistration request - * 1 for registration request - */ - void sendRegister( const ::std::string& accountId , const int32_t& enable); - - bool getCallStatus(const std::string& sequenceId); - - /** - * Get account list - * @return std::vector<std::string> A list of accoundIDs - */ - std::vector< std::string > getAccountList(); - - /** - * Set the account order in the config file - */ - void setAccountsOrder (const std::string& order); - - /** - * Load the accounts order set by the user from the sflphonedrc config file - * @return std::vector<std::string> A vector containing the account ID's - */ - std::vector<std::string> loadAccountOrder (); - - /** - * Retrieve details about a given account - * @param accountID The account identifier - * @return std::map< std::string, std::string > The account details - */ - std::map< std::string, std::string > getAccountDetails(const AccountID& accountID); - - /** - * Retrieve details about a given call - * @param callID The account identifier - * @return std::map< std::string, std::string > The call details - */ - std::map< std::string, std::string > getCallDetails(const CallID& callID); - - /** - * Get call list - * @return std::vector<std::string> A list of call IDs - */ - std::vector< std::string > getCallList (void); - - /** - * Retrieve details about a given call - * @param callID The account identifier - * @return std::map< std::string, std::string > The call details - */ - std::map< std::string, std::string > getConferenceDetails(const CallID& callID); - - /** - * Get call list - * @return std::vector<std::string> A list of call IDs - */ - std::vector< std::string > getConferenceList (void); - - - /** - * Get a list of participant to a conference - * @return std::vector<std::string> A list of call IDs - */ - std::vector< std::string > getParticipantList (const std::string& confID); - - /** - * Save the details of an existing account, given the account ID - * This will load the configuration map with the given data. - * It will also register/unregister links where the 'Enabled' switched. - * @param accountID The account identifier - * @param details The account parameters - */ - void setAccountDetails( const ::std::string& accountID, - const std::map< ::std::string, ::std::string >& details ); - - /** - * Add a new account, and give it a new account ID automatically - * @param details The new account parameters - * @return The account Id given to the new account - */ - std::string addAccount(const std::map< ::std::string, ::std::string >& details); - - /** - * Delete an existing account, unregister VoIPLink associated, and - * purge from configuration. - * @param accountID The account unique ID - */ - void removeAccount(const AccountID& accountID); - - - /** - * Deletes all credentials defined for an account - * @param accountID The account unique ID - */ - void deleteAllCredential(const AccountID& accountID); - - /** - * Get current codec name - * @param call id - * @return std::string The codec name - */ - std::string getCurrentCodecName(const CallID& id); - - /** - * Set input audio plugin - * @param audioPlugin The audio plugin - */ - void setInputAudioPlugin(const std::string& audioPlugin); - - /** - * Set output audio plugin - * @param audioPlugin The audio plugin - */ - void setOutputAudioPlugin(const std::string& audioPlugin); - - /** - * Get list of supported audio output device - * @return std::vector<std::string> A list of the audio devices supporting playback - */ - std::vector<std::string> getAudioOutputDeviceList(void); - - /** - * Set audio device - * @param index The index of the soundcard - * @param the type of stream, either SFL_PCM_PLAYBACK, SFL_PCM_CAPTURE, SFL_PCM_RINGTONE - */ - void setAudioDevice(const int index, const int streamType); - - /** - * Get list of supported audio input device - * @return std::vector<std::string> A list of the audio devices supporting capture - */ - std::vector<std::string> getAudioInputDeviceList(void); - - /** - * Get string array representing integer indexes of output and input device - * @return std::vector<std::string> A list of the current audio devices - */ - std::vector<std::string> getCurrentAudioDevicesIndex(); - - /** - * Get index of an audio device - * @param name The string description of an audio device - * @return int His index - */ - int getAudioDeviceIndex( const std::string name ); - - /** - * Get current alsa plugin - * @return std::string The Alsa plugin - */ - std::string getCurrentAudioOutputPlugin( void ); - - std::string getEchoCancelState(void); - - void setEchoCancelState(std::string state); - - std::string getNoiseSuppressState(void); - - void setNoiseSuppressState(std::string state); - - /** - * Convert a list of payload in a special format, readable by the server. - * Required format: payloads separated with one slash. - * @return std::string The serializabled string - */ - std::string serialize(std::vector<std::string> v); - - std::vector<std::string> unserialize(std::string v); - - /** - * Tells if IAX2 support is enabled - * @return int 1 if IAX2 is enabled - * 0 otherwise - */ - int isIax2Enabled( void ); - - /** - * Ringtone option. - * If ringtone is enabled, ringtone on incoming call use custom choice. If not, only standart tone. - * @return int 1 if enabled - * 0 otherwise - */ - int isRingtoneEnabled( void ); - - /** - * Set the ringtone option - * Inverse current value - */ - void ringtoneEnabled( void ); - - /** - * Get the ringtone - * @return gchar* The file name selected as a ringtone - */ - std::string getRingtoneChoice( void ); - - /** - * Set a ringtone - * @param tone The file name of the ringtone - */ - void setRingtoneChoice( const std::string& ); - - /** - * Get the recording path from configuration tree - * @return the string correspoding to the path - */ - std::string getRecordPath( void ); - - /** - * Set the recoding path in the configuration tree - * @param a string reresenting the path - */ - void setRecordPath( const std::string& recPath); - - /** - * Set a credential for a given account. If it - * does not exist yet, it will be created. - */ - void setCredential (const std::string& accountID, const int32_t& index, const std::map< std::string, std::string >& details); - - /** - * Retreive the value set in the configuration file. - * @return True if credentials hashing is enabled. - */ - bool getMd5CredentialHashing(void); - - /** - * Tells if the user wants to display the dialpad or not - * @return int 1 if dialpad has to be displayed - * 0 otherwise - */ - int getDialpad( void ); - - /** - * Set the dialpad visible or not - */ - void setDialpad (bool display); - - /** - * Tells if the user wants to display the volume controls or not - * @return int 1 if the controls have to be displayed - * 0 otherwise - */ - int getVolumeControls( void ); - - /** - * Set the volume controls ( mic and speaker ) visible or not - */ - void setVolumeControls (bool display); - - /** - * Set recording on / off - * Start recording - * @param id The call identifier - */ - void setRecordingCall(const CallID& id); - - /** - * Return true if the call is currently recorded - */ - bool isRecording(const CallID& id); - - /** - * Set the maximum number of days to keep in the history - * @param calls The number of days - */ - void setHistoryLimit (const int& days); - - /** - * Get the maximum number of days to keep in the history - * @return double The number of days - */ - int getHistoryLimit (void); - - void setHistoryEnabled (void); - - std::string getHistoryEnabled (void); - - - /** - * Configure the start-up option - * @return int 1 if SFLphone should start in the system tray - * 0 otherwise - */ - int isStartHidden( void ); - - /** - * Configure the start-up option - * At startup, SFLphone can be displayed or start hidden in the system tray - */ - void startHidden( void ); - - /** - * Configure the popup behaviour - * @return int 1 if it should popup on incoming calls - * 0 if it should never popups - */ - int popupMode( void ); - - /** - * Configure the popup behaviour - * When SFLphone is in the system tray, you can configure when it popups - * Never or only on incoming calls - */ - void switchPopupMode( void ); - - /** - * Determine whether or not the search bar (history) should be displayed - */ - int getSearchbar( void ); - - /** - * Configure the search bar behaviour - */ - void setSearchbar( void ); - - /** - * Set the desktop notification level - */ - void setNotify( void ); - - /** - * Get the desktop notification level - * @return int The notification level - */ - int32_t getNotify( void ); - - /** - * Set the desktop mail notification level - */ - void setMailNotify( void ); - - - /** - * Addressbook configuration - */ - std::map<std::string, int32_t> getAddressbookSettings (void); - - /** - * Addressbook configuration - */ - void setAddressbookSettings (const std::map<std::string, int32_t>& settings); - - /** - * Addressbook list - */ - void setAddressbookList(const std::vector< std::string >& list); - - /** - * Addressbook list - */ - std::vector <std::string> getAddressbookList( void ); - - /** - * Hook configuration - */ - std::map<std::string, std::string> getHookSettings (void); - - /** - * Hook configuration - */ - void setHookSettings (const std::map<std::string, std::string>& settings); - - - /** - * Get the audio manager - * @return int The audio manager - * 0 ALSA - * 1 PULSEAUDIO - */ - int32_t getAudioManager( void ); - - /** - * Set the audio manager - */ - void setAudioManager( const int32_t& api ); - - void switchAudioManager( void ); - - void audioSamplingRateChanged( void ); - - /** - * Get the desktop mail notification level - * @return int The mail notification level - */ - int32_t getMailNotify( void ); - - /** - * Retrieve the formatted list of codecs payload in the user config file and - * load in the active list of codecs - * @return std::vector<std::string> The vector containing the active codecs - */ - std::vector<std::string> retrieveActiveCodecs( void ); - - /** - * Get the list of the active codecs - * @return std::vector< ::std::string > The list of active codecs - */ - std::vector< ::std::string > getActiveCodecList( void ); - - /* - * Notify the client that an error occured - * @param errCode The error code. Could be: ALSA_CAPTURE_ERROR - * ALSA_PLAYBACK_ERROR - */ - void notifyErrClient( const int32_t& errCode ); - - /** - * Retrieve in the configuration tree the value of a parameter in a specific section - * @param section The section to look in - * @param name The name of the parameter you want to get - * @param arg Undocumented - * @return bool true on success - * false otherwise - */ - bool getConfig(const std::string& section, const std::string& name, TokenList& arg); - - /** - * Change a specific value in the configuration tree. - * This value will then be saved in the user config file sflphonedrc - * @param section The section name - * @param name The parameter name - * @param value The new string value - * @return bool true on success - * false otherwise - */ - bool setConfig(const std::string& section, const std::string& name, const std::string& value); - - /** - * Change a specific value in the configuration tree. - * This value will then be saved in the user config file sflphonedrc - * @param section The section name - * @param name The parameter name - * @param value The new int value - * @return bool true on success - * false otherwise - */ - bool setConfig(const std::string& section, const std::string& name, int value); - - inline std::string mapStateNumberToString(RegistrationState state) { - std::string stringRepresentation; - if (state > NumberOfState) { - stringRepresentation = "ERROR"; +class ManagerImpl +{ + public: + ManagerImpl (void); + ~ManagerImpl (void); + + + /** + * General preferences configuration + */ + Preferences preferences; + + /** + * Voip related preferences + */ + VoipPreference voipPreferences; + + /** + * Addressbook related preferences + */ + AddressbookPreference addressbookPreference; + + /** + * Hook preferences + */ + HookPreference hookPreference; + + /** + * Audio preferences + */ + AudioPreference audioPreference; + + /** + * Shortcut preferences + */ + ShortcutPreferences shortcutPreferences; + + /** + * Method to build preferences from configuration + */ + short buildConfiguration(); + + /** + * Initialisation of thread (sound) and map. + * Init a new VoIPLink, audio codec and audio driver + */ + void init (void); + + /** + * Terminate all thread (sound, link) and unload AccountMap + */ + void terminate (void); + + /** + * Set user interface manager. + * @param man The DBUS interface implementation + */ + void setDBusManager (DBusManagerImpl* man) { + _dbus = man; + } + + /** + * Accessor to audiodriver. + * it's multi-thread and use mutex internally + * @return AudioLayer* The audio layer object + */ + AudioLayer* getAudioDriver (void) const { + return _audiodriver; + } + + /** + * Get a descriptor map of codec available + * @return CodecDescriptor The internal codec map + */ + CodecDescriptor& getCodecDescriptorMap (void) { + return _codecDescriptorMap; + } + + /** + * Functions which occur with a user's action + * Place a new call + * @param accountId The account to make tha call with + * @param id The call identifier + * @param to The recipient of the call + * @return bool true on success + * false otherwise + */ + bool outgoingCall (const AccountID& accountId, const CallID& id, const std::string& to); + + /** + * Functions which occur with a user's action + * Answer the call + * @param id The call identifier + */ + bool answerCall (const CallID& id); + + /** + * Functions which occur with a user's action + * Hangup the call + * @param id The call identifier + */ + bool hangupCall (const CallID& id); + + + /** + * Functions which occur with a user's action + * Hangup the conference (hangup every participants) + * @param id The call identifier + */ + bool hangupConference (const ConfID& id); + + /** + * Functions which occur with a user's action + * Cancel the call + * @param id The call identifier + */ + bool cancelCall (const CallID& id); + + /** + * Functions which occur with a user's action + * Put the call on hold + * @param id The call identifier + */ + bool onHoldCall (const CallID& id); + + /** + * Functions which occur with a user's action + * Put the call off hold + * @param id The call identifier + */ + bool offHoldCall (const CallID& id); + + /** + * Functions which occur with a user's action + * Transfer the call + * @param id The call identifier + * @param to The recipient of the transfer + */ + bool transferCall (const CallID& id, const std::string& to); + + /** + * Notify the client the transfer is successful + */ + void transferSucceded(); + + /** + * Notify the client that the transfer failed + */ + void transferFailed(); + + /** + * Functions which occur with a user's action + * Refuse the call + * @param id The call identifier + */ + bool refuseCall (const CallID& id); + + /** + * Create a new conference given two participant + * @param the first participant ID + * @param the second participant ID + */ + Conference* createConference (const CallID& id1, const CallID& id2); + + /** + * Delete this conference + * @param the conference ID + */ + void removeConference (const CallID& conference_id); + + /** + * Return the conference id for which this call is attached + * @ param the call id + */ + Conference* getConferenceFromCallID (const CallID& call_id); + + /** + * Hold every participant to a conference + * @param the conference id + */ + void holdConference (const CallID& conferece_id); + + /** + * Unhold all conference participants + * @param the conference id + */ + void unHoldConference (const CallID& conference_id); + + /** + * Test if this id is a conference (usefull to test current call) + * @param the call id + */ + bool isConference (const CallID& call_id); + + /** + * Test if a call id particips to this conference + * @param the call id + */ + bool participToConference (const CallID& call_id); + + /** + * Add a participant to a conference + * @param the call id + * @param the conference id + */ + void addParticipant (const CallID& call_id, const CallID& conference_id); + + /** + * Bind the main participant to a conference (mainly called on a double click action) + * @param the conference id + */ + void addMainParticipant (const CallID& conference_id); + + /** + * Join two participants to create a conference + * @param the fist call id + * @param the second call id + */ + void joinParticipant (const CallID& call_id1, const CallID& call_id2); + + /** + * Detach a participant from a conference, put the call on hold, do not hangup it + * @param call id + * @param the current call id + */ + void detachParticipant (const CallID& call_id, const CallID& current_call_id); + + /** + * Remove the conference participant from a conference + * @param call id + */ + void removeParticipant (const CallID& call_id); + + /** + * Process remaining participant given a conference and the current call id. + * Mainly called when a participant is detached or hagned up + * @param current call id + * @param conference pointer + */ + void processRemainingParticipant (CallID current_call_id, Conference *conf); + + /** + * Join two conference together into one unique conference + */ + void joinConference (const CallID& conf_id1, const CallID& conf_id2); + + void addStream (const CallID& call_id); + + void removeStream (const CallID& call_id); + + /** + * Save config to file + * @return true on success + * false otherwise + */ + bool saveConfig (void); + + /** + * Send registration to all enabled accounts + * @return 0 on registration success + * 1 otherelse + */ + int initRegisterAccounts(); + + /** + * @return true if we tried to register once + */ + bool _hasTriedToRegister; + + /** + * Handle choice of the DTMF-send-way + * @param id: callid of the line. + * @param code: pressed key. + */ + bool sendDtmf (const CallID& id, char code); + + /** + * Play the dtmf-associated sound + * @param code The pressed key + */ + bool playDtmf (char code); + + /** + * Play a ringtone + * @return bool True on success + * false otherwise + */ + bool playTone (); + + /** + * Play a special ringtone ( BUSY ) if there's at least one message on the voice mail + * @return bool True on success + * false otherwise + */ + bool playToneWithMessage (); + + /** + * Acts on the audio streams and audio files + */ + void stopTone (void); + + /** + * When receiving a new incoming call, add it to the callaccount map + * and notify user + * @param call A call pointer + * @param accountId an account id + * @return bool True if the call was added correctly + */ + bool incomingCall (Call* call, const AccountID& accountId); + + /** + * Notify the user that the recipient of the call has answered and the put the + * call in Current state + * @param id The call identifier + */ + void peerAnsweredCall (const CallID& id); + + /** + * Rings back because the outgoing call is ringing and the put the + * call in Ringing state + * @param id The call identifier + */ + void peerRingingCall (const CallID& id); + + /** + * Put the call in Hungup state, remove the call from the list + * @param id The call identifier + */ + void peerHungupCall (const CallID& id); + + /** + * Notify the client with an incoming message + * @param accountId The account identifier + * @param message The content of the message + */ + void incomingMessage (const CallID& callID, const std::string& from, const std::string& message); + + /** + * Notify the client he has voice mails + * @param accountId The account identifier + * @param nb_msg The number of messages + */ + void startVoiceMessageNotification (const AccountID& accountId, int nb_msg); + + /** + * Notify the client through DBus that registration state has been updated + */ + void connectionStatusNotification (void); + + /** + * ConfigurationManager - Send registration request + * @param accountId The account to register/unregister + * @param enable The flag for the type of registration + * 0 for unregistration request + * 1 for registration request + */ + void sendRegister (const ::std::string& accountId , const int32_t& enable); + + bool getCallStatus (const std::string& sequenceId); + + /** + * Get account list + * @return std::vector<std::string> A list of accoundIDs + */ + std::vector< std::string > getAccountList(); + + /** + * Set the account order in the config file + */ + void setAccountsOrder (const std::string& order); + + /** + * Load the accounts order set by the user from the sflphonedrc config file + * @return std::vector<std::string> A vector containing the account ID's + */ + std::vector<std::string> loadAccountOrder (); + + /** + * Retrieve details about a given account + * @param accountID The account identifier + * @return std::map< std::string, std::string > The account details + */ + std::map< std::string, std::string > getAccountDetails (const AccountID& accountID); + + /** + * Retrieve details about a given call + * @param callID The account identifier + * @return std::map< std::string, std::string > The call details + */ + std::map< std::string, std::string > getCallDetails (const CallID& callID); + + /** + * Get call list + * @return std::vector<std::string> A list of call IDs + */ + std::vector< std::string > getCallList (void); + + /** + * Retrieve details about a given call + * @param callID The account identifier + * @return std::map< std::string, std::string > The call details + */ + std::map< std::string, std::string > getConferenceDetails (const CallID& callID); + + /** + * Get call list + * @return std::vector<std::string> A list of call IDs + */ + std::vector< std::string > getConferenceList (void); + + + /** + * Get a list of participant to a conference + * @return std::vector<std::string> A list of call IDs + */ + std::vector< std::string > getParticipantList (const std::string& confID); + + /** + * Save the details of an existing account, given the account ID + * This will load the configuration map with the given data. + * It will also register/unregister links where the 'Enabled' switched. + * @param accountID The account identifier + * @param details The account parameters + */ + void setAccountDetails (const ::std::string& accountID, + const std::map< ::std::string, ::std::string >& details); + + /** + * Add a new account, and give it a new account ID automatically + * @param details The new account parameters + * @return The account Id given to the new account + */ + std::string addAccount (const std::map< ::std::string, ::std::string >& details); + + /** + * Delete an existing account, unregister VoIPLink associated, and + * purge from configuration. + * @param accountID The account unique ID + */ + void removeAccount (const AccountID& accountID); + + + /** + * Deletes all credentials defined for an account + * @param accountID The account unique ID + */ + void deleteAllCredential (const AccountID& accountID); + + /** + * Get current codec name + * @param call id + * @return std::string The codec name + */ + std::string getCurrentCodecName (const CallID& id); + + /** + * Set input audio plugin + * @param audioPlugin The audio plugin + */ + void setAudioPlugin (const std::string& audioPlugin); + + /** + * Set audio device + * @param index The index of the soundcard + * @param the type of stream, either SFL_PCM_PLAYBACK, SFL_PCM_CAPTURE, SFL_PCM_RINGTONE + */ + void setAudioDevice (const int index, const int streamType); + + /** + * Get list of supported audio output device + * @return std::vector<std::string> A list of the audio devices supporting playback + */ + std::vector<std::string> getAudioOutputDeviceList (void); + + /** + * Get list of supported audio input device + * @return std::vector<std::string> A list of the audio devices supporting capture + */ + std::vector<std::string> getAudioInputDeviceList (void); + + /** + * Get string array representing integer indexes of output, input, and ringtone device + * @return std::vector<std::string> A list of the current audio devices + */ + std::vector<std::string> getCurrentAudioDevicesIndex(); + + /** + * Get index of an audio device + * @param name The string description of an audio device + * @return int His index + */ + int getAudioDeviceIndex (const std::string name); + + /** + * Get current alsa plugin + * @return std::string The Alsa plugin + */ + std::string getCurrentAudioOutputPlugin (void); + + std::string getEchoCancelState (void); + + void setEchoCancelState (std::string state); + + std::string getNoiseSuppressState (void); + + void setNoiseSuppressState (std::string state); + + /** + * Convert a list of payload in a special format, readable by the server. + * Required format: payloads separated with one slash. + * @return std::string The serializabled string + */ + std::string serialize (std::vector<std::string> v); + + std::vector<std::string> unserialize (std::string v); + + /** + * Tells if IAX2 support is enabled + * @return int 1 if IAX2 is enabled + * 0 otherwise + */ + int isIax2Enabled (void); + + /** + * Ringtone option. + * If ringtone is enabled, ringtone on incoming call use custom choice. If not, only standart tone. + * @return int 1 if enabled + * 0 otherwise + */ + int isRingtoneEnabled (const AccountID& id); + + /** + * Set the ringtone option + * Inverse current value + */ + void ringtoneEnabled (const AccountID& id); + + /** + * Get the ringtone + * @return gchar* The file name selected as a ringtone + */ + std::string getRingtoneChoice (const AccountID& id); + + /** + * Set a ringtone + * @param tone The file name of the ringtone + */ + void setRingtoneChoice (const std::string&, const AccountID& id); + + /** + * Get the recording path from configuration tree + * @return the string correspoding to the path + */ + std::string getRecordPath (void); + + /** + * Set the recoding path in the configuration tree + * @param a string reresenting the path + */ + void setRecordPath (const std::string& recPath); + + /** + * Set a credential for a given account. If it + * does not exist yet, it will be created. + */ + void setCredential (const std::string& accountID, const int32_t& index, const std::map< std::string, std::string >& details); + + /** + * Retreive the value set in the configuration file. + * @return True if credentials hashing is enabled. + */ + bool getMd5CredentialHashing (void); + + /** + * Tells if the user wants to display the dialpad or not + * @return int 1 if dialpad has to be displayed + * 0 otherwise + */ + // int getDialpad( void ); + + /** + * Set the dialpad visible or not + */ + // void setDialpad (bool display); + + /** + * Tells if the user wants to display the volume controls or not + * @return int 1 if the controls have to be displayed + * 0 otherwise + */ + // int getVolumeControls( void ); + + /** + * Set the volume controls ( mic and speaker ) visible or not + */ + // void setVolumeControls (bool display); + + /** + * Set recording on / off + * Start recording + * @param id The call identifier + */ + void setRecordingCall (const CallID& id); + + /** + * Return true if the call is currently recorded + */ + bool isRecording (const CallID& id); + + /** + * Set the maximum number of days to keep in the history + * @param calls The number of days + */ + void setHistoryLimit (const int& days); + + /** + * Get the maximum number of days to keep in the history + * @return double The number of days + */ + int getHistoryLimit (void); + + // void setHistoryEnabled (void); + + // std::string getHistoryEnabled (void); + + + /** + * Configure the start-up option + * @return int 1 if SFLphone should start in the system tray + * 0 otherwise + */ + int isStartHidden (void); + + /** + * Configure the start-up option + * At startup, SFLphone can be displayed or start hidden in the system tray + */ + void startHidden (void); + + /** + * Configure the popup behaviour + * @return int 1 if it should popup on incoming calls + * 0 if it should never popups + */ + // int popupMode( void ); + + /** + * Configure the popup behaviour + * When SFLphone is in the system tray, you can configure when it popups + * Never or only on incoming calls + */ + // void switchPopupMode( void ); + + /** + * Determine whether or not the search bar (history) should be displayed + */ + // int getSearchbar( void ); + + /** + * Configure the search bar behaviour + */ + // void setSearchbar( void ); + + /** + * Set the desktop notification level + */ + // void setNotify( void ); + + /** + * Get the desktop notification level + * @return int The notification level + */ + // int32_t getNotify( void ); + + /** + * Set the desktop mail notification level + */ + void setMailNotify (void); + + + /** + * Addressbook configuration + */ + std::map<std::string, int32_t> getAddressbookSettings (void); + + /** + * Addressbook configuration + */ + void setAddressbookSettings (const std::map<std::string, int32_t>& settings); + + /** + * Addressbook list + */ + void setAddressbookList (const std::vector< std::string >& list); + + /** + * Addressbook list + */ + std::vector <std::string> getAddressbookList (void); + + /** + * Hook configuration + */ + std::map<std::string, std::string> getHookSettings (void); + + /** + * Hook configuration + */ + void setHookSettings (const std::map<std::string, std::string>& settings); + + + /** + * Get the audio manager + * @return int The audio manager + * 0 ALSA + * 1 PULSEAUDIO + */ + int32_t getAudioManager (void); + + /** + * Set the audio manager + */ + void setAudioManager (const int32_t& api); + + void switchAudioManager (void); + + void audioSamplingRateChanged (void); + + /** + * Get the desktop mail notification level + * @return int The mail notification level + */ + int32_t getMailNotify (void); + + /** + * Retrieve the formatted list of codecs payload in the user config file and + * load in the active list of codecs + * @return std::vector<std::string> The vector containing the active codecs + */ + std::vector<std::string> retrieveActiveCodecs (void); + + /** + * Get the list of the active codecs + * @return std::vector< ::std::string > The list of active codecs + */ + std::vector< ::std::string > getActiveCodecList (void); + + /* + * Notify the client that an error occured + * @param errCode The error code. Could be: ALSA_CAPTURE_ERROR + * ALSA_PLAYBACK_ERROR + */ + void notifyErrClient (const int32_t& errCode); + + /** + * Retrieve in the configuration tree the value of a parameter in a specific section + * @param section The section to look in + * @param name The name of the parameter you want to get + * @param arg Undocumented + * @return bool true on success + * false otherwise + */ + bool getConfig (const std::string& section, const std::string& name, TokenList& arg); + + /** + * Change a specific value in the configuration tree. + * This value will then be saved in the user config file sflphonedrc + * @param section The section name + * @param name The parameter name + * @param value The new string value + * @return bool true on success + * false otherwise + */ + bool setConfig (const std::string& section, const std::string& name, const std::string& value); + + /** + * Change a specific value in the configuration tree. + * This value will then be saved in the user config file sflphonedrc + * @param section The section name + * @param name The parameter name + * @param value The new int value + * @return bool true on success + * false otherwise + */ + bool setConfig (const std::string& section, const std::string& name, int value); + + inline std::string mapStateNumberToString (RegistrationState state) { + std::string stringRepresentation; + + if (state > NumberOfState) { + stringRepresentation = "ERROR"; + return stringRepresentation; + } + + stringRepresentation = mapStateToChar[state]; return stringRepresentation; } - - stringRepresentation = mapStateToChar[state]; - return stringRepresentation; - } - - /** - * Get a int from the configuration tree - * Throw an Conf::ConfigTreeItemException if not found - * @param section The section name to look in - * @param name The parameter name - * @return int The int value - */ - - int getConfigInt(const std::string& section, const std::string& name); - - /** - * Get a bool from the configuration tree - * Throw an Conf::ConfigTreeItemException if not found - * @param section The section name to look in - * @param name The parameter name - * @return bool The bool value - */ - - bool getConfigBool(const std::string& section, const std::string& name); - - /** - * Get a string from the configuration tree - * Throw an Conf::ConfigTreeItemException if not found - * @param section The section name to look in - * @param name The parameter name - * @return sdt::string The string value - */ - std::string getConfigString(const std::string& section, const std::string& name); - - /** - * Retrieve the soundcards index in the user config file and try to open audio devices - * with a specific alsa plugin. - * Set the audio layer sample rate - */ - void selectAudioDriver(void); - - /** - * Handle audio sounds heard by a caller while they wait for their - * connection to a called party to be completed. - */ - void ringback (); - - /** - * Handle played music when an incoming call occurs - */ - void ringtone (); - - /** - * Handle played music when a congestion occurs - */ - void congestion (); - - /** - * Handle played sound when a call can not be conpleted because of a busy recipient - */ - void callBusy(const CallID& id); - - /** - * Handle played sound when a failure occurs - */ - void callFailure(const CallID& id); - - /** - * Retrieve the current telephone tone - * @return AudioLoop* The audio tone or 0 if no tone (init before calling this function) - */ - AudioLoop* getTelephoneTone(); - - /** - * Retrieve the current telephone file - * @return AudioLoop* The audio file or 0 if the wav is stopped - */ - AudioLoop* getTelephoneFile(); - - /** - * @return true is there is one or many incoming call waiting - * new call, not anwsered or refused - */ - bool incomingCallWaiting(void); - - /** - * Notification of incoming call when you are already busy - */ - void notificationIncomingCall(void); - - /* - * Inline functions to manage speaker volume control - * Read by main thread and AudioLayer thread - * Write by main thread only - * @return unsigned short The volume value - */ - unsigned short getSpkrVolume(void) { return _spkr_volume; } - - /* - * Inline functions to manage speaker volume control - * Read by main thread and AudioLayer thread - * Write by main thread only - * @param spkr_vol The volume value - */ - void setSpkrVolume(unsigned short spkr_vol); - - /* - * Inline functions to manage mic volume control - * Read by main thread and AudioLayer thread - * Write by main thread only - * @return unsigned short The volume value - */ - unsigned short getMicVolume(void) { return _mic_volume; } - - /* - * Inline functions to manage mic volume control - * Read by main thread and AudioLayer thread - * Write by main thread only - * @param mic_vol The volume value - */ - void setMicVolume(unsigned short mic_vol); - - /** - * Init default values for the different fields in the config file. - * Fills the local _config (Conf::ConfigTree) with the default contents. - * Called in main.cpp, just before Manager::init(). - */ - void initConfigFile ( bool load_user_value=true, std::string alternate=""); - - /** - * Tell if the setup was already loaded - * @return bool True if yes - * false otherwise - */ - bool hasLoadedSetup() { return _setupLoaded; } - - /** - * Return a new random callid that is not present in the list - * @return CallID A brand new callid - */ - CallID getNewCallID(); - - /** - * Get the current call id - * @return CallID The call id or "" - */ - const CallID& getCurrentCallId(); - - /** - * Check if a call is the current one - * @param callId the new callid - * @return bool True if the id is the current call - */ - bool isCurrentCall(const CallID& callId); - - - /** - * Send registration to all enabled accounts - * @return 0 on registration success - * 1 otherelse - */ - int registerAccounts(); - - /** - * Restart PJSIP - * @param void - * @return void - */ - void restartPJSIP( ); - - void unregisterCurSIPAccounts (void); - - void registerCurSIPAccounts (void); - - /* - * Initialize audiodriver - */ - bool initAudioDriver(void); - - ost::Mutex* getAudioLayerMutex() { return &_audiolayer_mutex; } - - private: - /* Transform digest to string. - * output must be at least PJSIP_MD5STRLEN+1 bytes. - * Helper function taken from sip_auth_client.c in - * pjproject-1.0.3. - * - * NOTE: THE OUTPUT STRING IS NOT NULL TERMINATED! - */ - void digest2str(const unsigned char digest[], char *output); - - /** - * Helper function that creates an MD5 Hash from the credential - * information provided as parameters. The hash is computed as - * MD5(username ":" realm ":" password). - * - */ - std::string computeMd5HashFromCredential(const std::string& username, const std::string& password, const std::string& realm); - - /** - * Check if a process is running with the system command - * - * @return 0 on success - * 1 otherelse - */ - int app_is_running(std::string process); - - /** - * Create .PROGNAME directory in home user and create - * configuration tree from the settings file if this file exists. - * - * @return 0 if creating file failed - * 1 if config-file exists - * 2 if file doesn't exist yet. - */ - int createSettingsPath (void); - - /* - * Initialize audiocodec with config setting - */ - void initAudioCodec(void); - - - /* - * Initialize zeroconf module and scanning - */ - void initZeroconf(void); - - /* - * Init the volume for speakers/micro from 0 to 100 value - */ - void initVolume(); - - /** - * Switch of current call id - * @param id The new callid - */ - void switchCall(const CallID& id); - - /* - * Play one tone - * @return false if the driver is uninitialize - */ - bool playATone(Tone::TONEID toneId); - - /** The configuration tree. It contains accounts parameters, general user settings ,audio settings, ... */ - Conf::ConfigTree _config; - - /** Current Call ID */ - CallID _currentCallId2; - - /** Protected current call access */ - ost::Mutex _currentCallMutex; - - /** Vector of CodecDescriptor */ - CodecDescriptor* _codecBuilder; - - /** Audio layer */ - AudioLayer* _audiodriver; - - // Main thread - - DTMF* _dtmfKey; - - // map of codec (for configlist request) - CodecDescriptor _codecDescriptorMap; - - ///////////////////// - // Protected by Mutex - ///////////////////// - ost::Mutex _toneMutex; - TelephoneTone* _telephoneTone; - AudioFile _audiofile; - - // To handle volume control - short _spkr_volume; - short _mic_volume; - // End of sound variable - - - // Multithread variable (protected by _mutex) - // - /** Mutex to protect access to code section */ - ost::Mutex _mutex; - - ost::Mutex _audiolayer_mutex; - - // Multithread variable (non protected) - DBusManagerImpl * _dbus; - - /** Waiting Call Vectors */ - CallIDSet _waitingCall; - - /** Protect waiting call list, access by many voip/audio threads */ - ost::Mutex _waitingCallMutex; - - /** Number of waiting call, synchronize with waitingcall callidvector */ - unsigned int _nbIncomingWaitingCall; - - /** - * Add incoming callid to the waiting list - * @param id CallID to add - */ - void addWaitingCall(const CallID& id); - - /** - * Remove incoming callid to the waiting list - * @param id CallID to remove - */ - void removeWaitingCall(const CallID& id); - - /** - * Tell if a call is waiting and should be remove - * @param id CallID to test - * @return bool True if the call is waiting - */ - bool isWaitingCall(const CallID& id); - - /** - * Path of the ConfigFile - */ - std::string _path; - int _exist; - int _setupLoaded; + + /** + * Get a int from the configuration tree + * Throw an Conf::ConfigTreeItemException if not found + * @param section The section name to look in + * @param name The parameter name + * @return int The int value + */ + + int getConfigInt (const std::string& section, const std::string& name); + + /** + * Get a bool from the configuration tree + * Throw an Conf::ConfigTreeItemException if not found + * @param section The section name to look in + * @param name The parameter name + * @return bool The bool value + */ + + bool getConfigBool (const std::string& section, const std::string& name); + + /** + * Get a string from the configuration tree + * Throw an Conf::ConfigTreeItemException if not found + * @param section The section name to look in + * @param name The parameter name + * @return sdt::string The string value + */ + std::string getConfigString (const std::string& section, const std::string& name); + + /** + * Retrieve the soundcards index in the user config file and try to open audio devices + * with a specific alsa plugin. + * Set the audio layer sample rate + */ + void selectAudioDriver (void); + + /** + * Handle audio sounds heard by a caller while they wait for their + * connection to a called party to be completed. + */ + void ringback (); + + /** + * Handle played music when an incoming call occurs + */ + void ringtone (const AccountID& accountID); + + /** + * Handle played music when a congestion occurs + */ + void congestion (); + + /** + * Handle played sound when a call can not be conpleted because of a busy recipient + */ + void callBusy (const CallID& id); + + /** + * Handle played sound when a failure occurs + */ + void callFailure (const CallID& id); + + /** + * Retrieve the current telephone tone + * @return AudioLoop* The audio tone or 0 if no tone (init before calling this function) + */ + AudioLoop* getTelephoneTone(); + + /** + * Retrieve the current telephone file + * @return AudioLoop* The audio file or 0 if the wav is stopped + */ + AudioLoop* getTelephoneFile(); + + /** + * @return true is there is one or many incoming call waiting + * new call, not anwsered or refused + */ + bool incomingCallWaiting (void); + + /** + * Notification of incoming call when you are already busy + */ + void notificationIncomingCall (void); + + /* + * Inline functions to manage speaker volume control + * Read by main thread and AudioLayer thread + * Write by main thread only + * @return unsigned short The volume value + */ + unsigned short getSpkrVolume (void) { + return _spkr_volume; + } + + /* + * Inline functions to manage speaker volume control + * Read by main thread and AudioLayer thread + * Write by main thread only + * @param spkr_vol The volume value + */ + void setSpkrVolume (unsigned short spkr_vol); + + /* + * Inline functions to manage mic volume control + * Read by main thread and AudioLayer thread + * Write by main thread only + * @return unsigned short The volume value + */ + unsigned short getMicVolume (void) { + return _mic_volume; + } + + /* + * Inline functions to manage mic volume control + * Read by main thread and AudioLayer thread + * Write by main thread only + * @param mic_vol The volume value + */ + void setMicVolume (unsigned short mic_vol); + + /** + * Init default values for the different fields in the config file. + * Fills the local _config (Conf::ConfigTree) with the default contents. + * Called in main.cpp, just before Manager::init(). + */ + void initConfigFile (bool load_user_value=true, std::string alternate=""); + + /** + * Tell if the setup was already loaded + * @return bool True if yes + * false otherwise + */ + bool hasLoadedSetup() { + return _setupLoaded; + } + + /** + * Return a new random callid that is not present in the list + * @return CallID A brand new callid + */ + CallID getNewCallID(); + + /** + * Get the current call id + * @return CallID The call id or "" + */ + const CallID& getCurrentCallId(); + + /** + * Check if a call is the current one + * @param callId the new callid + * @return bool True if the id is the current call + */ + bool isCurrentCall (const CallID& callId); + + + /** + * Send registration to all enabled accounts + * @return 0 on registration success + * 1 otherelse + */ + int registerAccounts(); + + /** + * Restart PJSIP + * @param void + * @return void + */ + void restartPJSIP(); + + void unregisterCurSIPAccounts (void); + + void registerCurSIPAccounts (void); + + /* + * Initialize audiodriver + */ + bool initAudioDriver (void); + + ost::Mutex* getAudioLayerMutex() { + return &_audiolayer_mutex; + } + + /** + * Helper function that creates an MD5 Hash from the credential + * information provided as parameters. The hash is computed as + * MD5(username ":" realm ":" password). + * + */ + std::string computeMd5HashFromCredential (const std::string& username, const std::string& password, const std::string& realm); + + private: + /* Transform digest to string. + * output must be at least PJSIP_MD5STRLEN+1 bytes. + * Helper function taken from sip_auth_client.c in + * pjproject-1.0.3. + * + * NOTE: THE OUTPUT STRING IS NOT NULL TERMINATED! + */ + void digest2str (const unsigned char digest[], char *output); + + /** + * Check if a process is running with the system command + * + * @return 0 on success + * 1 otherelse + */ + int app_is_running (std::string process); + + /** + * Create .PROGNAME directory in home user and create + * configuration tree from the settings file if this file exists. + * + * @return 0 if creating file failed + * 1 if config-file exists + * 2 if file doesn't exist yet. + */ + int createSettingsPath (void); + + /* + * Initialize audiocodec with config setting + */ + void initAudioCodec (void); + + + /* + * Initialize zeroconf module and scanning + */ + void initZeroconf (void); + + /* + * Init the volume for speakers/micro from 0 to 100 value + */ + void initVolume(); + + /** + * Switch of current call id + * @param id The new callid + */ + void switchCall (const CallID& id); + + /* + * Play one tone + * @return false if the driver is uninitialize + */ + bool playATone (Tone::TONEID toneId); + + /** The configuration tree. It contains accounts parameters, general user settings ,audio settings, ... */ + Conf::ConfigTree _config; + + /** Current Call ID */ + CallID _currentCallId2; + + /** Protected current call access */ + ost::Mutex _currentCallMutex; + + /** Vector of CodecDescriptor */ + CodecDescriptor* _codecBuilder; + + /** Audio layer */ + AudioLayer* _audiodriver; + + // Main thread + + DTMF* _dtmfKey; + + // map of codec (for configlist request) + CodecDescriptor _codecDescriptorMap; + + ///////////////////// + // Protected by Mutex + ///////////////////// + ost::Mutex _toneMutex; + TelephoneTone* _telephoneTone; + AudioFile *_audiofile; + + // To handle volume control + short _spkr_volume; + short _mic_volume; + // End of sound variable + + + // Multithread variable (protected by _mutex) + // + /** Mutex to protect access to code section */ + ost::Mutex _mutex; + + ost::Mutex _audiolayer_mutex; + + // Multithread variable (non protected) + DBusManagerImpl * _dbus; + + /** Waiting Call Vectors */ + CallIDSet _waitingCall; + + /** Protect waiting call list, access by many voip/audio threads */ + ost::Mutex _waitingCallMutex; + + /** Number of waiting call, synchronize with waitingcall callidvector */ + unsigned int _nbIncomingWaitingCall; + + /** + * Add incoming callid to the waiting list + * @param id CallID to add + */ + void addWaitingCall (const CallID& id); + + /** + * Remove incoming callid to the waiting list + * @param id CallID to remove + */ + void removeWaitingCall (const CallID& id); + + /** + * Tell if a call is waiting and should be remove + * @param id CallID to test + * @return bool True if the call is waiting + */ + bool isWaitingCall (const CallID& id); + + /** + * Path of the ConfigFile + */ + std::string _path; + int _exist; + int _setupLoaded; #ifdef USE_ZEROCONF - // DNSService contain every zeroconf services - // configuration detected on the network - DNSService *_DNSService; + // DNSService contain every zeroconf services + // configuration detected on the network + DNSService *_DNSService; #endif - /** Map to associate a CallID to the good account */ - CallAccountMap _callAccountMap; - - /** Mutex to lock the call account map (main thread + voiplink thread) */ - ost::Mutex _callAccountMapMutex; - - CallConfigMap _callConfigMap; - - bool associateConfigToCall (const CallID& callID, Call::CallConfiguration config); - - Call::CallConfiguration getConfigFromCall(const CallID& callID); - - bool removeCallConfig(const CallID& callID); - - /** Associate a new CallID to a AccountID - * Protected by mutex - * @param callID the new CallID not in the list yet - * @param accountID the known accountID present in accountMap - * @return bool True if the new association is create - */ - bool associateCallToAccount(const CallID& callID, const AccountID& accountID); - - /** Remove a CallID/AccountID association - * Protected by mutex - * @param callID the CallID to remove - * @return bool True if association is removed - */ - bool removeCallAccount(const CallID& callID); - - /** - *Contains a list of account (sip, aix, etc) and their respective voiplink/calls */ - AccountMap _accountMap; - - Account * _directIpAccount; - - /** - * Load the account from configuration - * @return short Number of account - */ - short loadAccountMap(); + /** Map to associate a CallID to the good account */ + CallAccountMap _callAccountMap; + + /** Mutex to lock the call account map (main thread + voiplink thread) */ + ost::Mutex _callAccountMapMutex; + + CallConfigMap _callConfigMap; + + bool associateConfigToCall (const CallID& callID, Call::CallConfiguration config); + + Call::CallConfiguration getConfigFromCall (const CallID& callID); + + bool removeCallConfig (const CallID& callID); + + /** Associate a new CallID to a AccountID + * Protected by mutex + * @param callID the new CallID not in the list yet + * @param accountID the known accountID present in accountMap + * @return bool True if the new association is create + */ + bool associateCallToAccount (const CallID& callID, const AccountID& accountID); + + /** Remove a CallID/AccountID association + * Protected by mutex + * @param callID the CallID to remove + * @return bool True if association is removed + */ + bool removeCallAccount (const CallID& callID); + + /** + *Contains a list of account (sip, aix, etc) and their respective voiplink/calls */ + AccountMap _accountMap; + + Account * _directIpAccount; + + void loadIptoipProfile(); + + /** + * Load the account from configuration + * @return short Number of account + */ + short loadAccountMap(); + + /** + * Unload the account (delete them) + */ + void unloadAccountMap(); + + + /** + * Instance of the MainBuffer for the whole application + * + * In order to send signal to other parts of the application, one must pass through the mainbuffer. + * Audio instances must be registered into the MainBuffer and bound together via the ManagerImpl. + * + */ + MainBuffer _mainBuffer; + + + public: + + /** + * Return a pointer to the instance of the mainbuffer + */ + MainBuffer *getMainBuffer (void) { + return &_mainBuffer; + } + + + /** + * Tell if there is a current call processed + * @return bool True if there is a current call + */ + bool hasCurrentCall(); + + /** + * Return the current DBusManagerImpl + * @return A pointer to the DBusManagerImpl instance + */ + DBusManagerImpl * getDbusManager() { + return _dbus; + } + + /** + * Tell if an account exists + * @param accountID account ID check + * @return bool True if the account exists + * false otherwise + */ + bool accountExists (const AccountID& accountID); + + std::map<std::string, std::string> send_history_to_client (void); + + void receive_history_from_client (std::map<std::string, std::string> history); + /** + * Get an account pointer + * @param accountID account ID to get + * @return Account* The account pointer or 0 + */ + Account* getAccount (const AccountID& accountID); + + /** Return the AccountID from a CallID + * Protected by mutex + * @param callID the CallID in the list + * @return AccountID The accountID associated or "" if the callID is not found + */ + AccountID getAccountFromCall (const CallID& callID); + + /** + * Get the voip link from the account pointer + * @param accountID Account ID to get + * @return VoIPLink* The voip link from the account pointer or 0 + */ + VoIPLink* getAccountLink (const AccountID& accountID=AccountNULL); + + VoIPLink* getSIPAccountLink (void); + AccountID getAccountIdFromNameAndServer (const std::string& userName, const std::string& server); - /** - * Unload the account (delete them) - */ - void unloadAccountMap(); - + int getLocalIp2IpPort(); - /** - * Instance of the MainBuffer for the whole application - * - * In order to send signal to other parts of the application, one must pass through the mainbuffer. - * Audio instances must be registered into the MainBuffer and bound together via the ManagerImpl. - * - */ - MainBuffer _mainBuffer; + std::string getStunServer (void); + void setStunServer (const std::string &server); + int isStunEnabled (void); + void enableStun (void); - public: + // Map containing reference between conferences and calls + ConferenceCallMap _conferencecall; - /** - * Return a pointer to the instance of the mainbuffer - */ - MainBuffer *getMainBuffer(void) { return &_mainBuffer; } + // Map containing conference pointers + ConferenceMap _conferencemap; + private: - /** - * Tell if there is a current call processed - * @return bool True if there is a current call - */ - bool hasCurrentCall(); - - /** - * Return the current DBusManagerImpl - * @return A pointer to the DBusManagerImpl instance - */ - DBusManagerImpl * getDbusManager() { return _dbus; } - - /** - * Tell if an account exists - * @param accountID account ID check - * @return bool True if the account exists - * false otherwise - */ - bool accountExists(const AccountID& accountID); + // Copy Constructor + ManagerImpl (const ManagerImpl& rh); - std::map<std::string, std::string> send_history_to_client (void); + // Assignment Operator + ManagerImpl& operator= (const ManagerImpl& rh); - void receive_history_from_client (std::map<std::string, std::string> history); - /** - * Get an account pointer - * @param accountID account ID to get - * @return Account* The account pointer or 0 - */ - Account* getAccount(const AccountID& accountID); + NumberCleaner *_cleaner; - /** Return the AccountID from a CallID - * Protected by mutex - * @param callID the CallID in the list - * @return AccountID The accountID associated or "" if the callID is not found - */ - AccountID getAccountFromCall(const CallID& callID); + /** + * To handle the persistent history + */ + HistoryManager * _history; - /** - * Get the voip link from the account pointer - * @param accountID Account ID to get - * @return VoIPLink* The voip link from the account pointer or 0 - */ - VoIPLink* getAccountLink(const AccountID& accountID=AccountNULL); - - VoIPLink* getSIPAccountLink (void); - - AccountID getAccountIdFromNameAndServer(const std::string& userName, const std::string& server); - - int getLocalIp2IpPort(); - - std::string getStunServer (void); - void setStunServer (const std::string &server); - - int isStunEnabled (void); - void enableStun (void); - - // Map containing reference between conferences and calls - ConferenceCallMap _conferencecall; - - // Map containing conference pointers - ConferenceMap _conferencemap; - -private: - - // Copy Constructor - ManagerImpl(const ManagerImpl& rh); - - // Assignment Operator - ManagerImpl& operator=( const ManagerImpl& rh); - - NumberCleaner *_cleaner; + /** + * Check if the call is a classic call or a direct IP-to-IP call + */ + void check_call_configuration (const CallID& id, const std::string& to, Call::CallConfiguration *callConfig); - /** - * To handle the persistent history - */ - HistoryManager * _history; - - /** - * Check if the call is a classic call or a direct IP-to-IP call - */ - void check_call_configuration (const CallID& id, const std::string& to, Call::CallConfiguration *callConfig); + Conf::YamlParser *parser; + Conf::YamlEmitter *emitter; #ifdef TEST - bool testCallAccountMap(); - bool testAccountMap(); + bool testCallAccountMap(); + bool testAccountMap(); #endif - friend class ConfigurationTest; - friend class HistoryTest; + friend class ConfigurationTest; + friend class HistoryTest; }; #endif // __MANAGER_H__ diff --git a/sflphone-common/src/managerimpl_registration.cpp b/sflphone-common/src/managerimpl_registration.cpp index e5397d5eb9328878b2ddfd7f1c4655a8ef18735d..5f9be9bfca93b4f7eb547299b6c4060872ade2e7 100644 --- a/sflphone-common/src/managerimpl_registration.cpp +++ b/sflphone-common/src/managerimpl_registration.cpp @@ -58,7 +58,7 @@ ManagerImpl::registerAccounts() bool flag = true; AccountMap::iterator iter; - _debugInit ("Initiate VoIP Links Registration"); + _debugInit ("Manager: Initiate VoIP Links Registration"); iter = _accountMap.begin(); /* Loop on the account map previously loaded */ @@ -98,7 +98,7 @@ ManagerImpl::initRegisterAccounts() bool flag = true; AccountMap::iterator iter; - _debugInit ("Initiate VoIP Links Registration"); + _debugInit ("Manager: Initiate VoIP Links Registration"); iter = _accountMap.begin(); /* Loop on the account map previously loaded */ @@ -248,13 +248,16 @@ ManagerImpl::sendRegister (const std::string& accountID , const int32_t& enable) { // Update the active field - setConfig (accountID, CONFIG_ACCOUNT_ENABLE, (enable == 1) ? TRUE_STR:FALSE_STR); - Account* acc = getAccount (accountID); + + if (enable == 1) + acc->setEnabled (true); + else + acc->setEnabled (false); + acc->loadConfig(); // Test on the freshly updated value - if (acc->isEnabled()) { // Verify we aren't already registered, then register _debug ("Send register for account %s\n" , accountID.c_str()); diff --git a/sflphone-common/src/numbercleaner.h b/sflphone-common/src/numbercleaner.h index a45192e258841175031339e77fba1b5c43ae0cee..6a4c2198d9de9b5440f270fd31d192557e439a6b 100644 --- a/sflphone-common/src/numbercleaner.h +++ b/sflphone-common/src/numbercleaner.h @@ -35,7 +35,8 @@ #include "logger.h" #include <string> -class NumberCleaner { +class NumberCleaner +{ public: NumberCleaner (void); @@ -43,16 +44,20 @@ class NumberCleaner { std::string clean (std::string to_clean); - inline void set_phone_number_prefix (std::string prefix) { - _debug("Number: Set phone number prefix %s", _prefix.c_str()); _prefix = prefix; } + inline void set_phone_number_prefix (std::string prefix) { + _debug ("Number: Set phone number prefix %s", _prefix.c_str()); + _prefix = prefix; + } - inline std::string get_phone_number_prefix (void) { return _prefix; } + inline std::string get_phone_number_prefix (void) { + return _prefix; + } private: std::string _prefix; - void strip_char(std::string to_strip, std::string *num); + void strip_char (std::string to_strip, std::string *num); }; diff --git a/sflphone-common/src/observer.h b/sflphone-common/src/observer.h index 5e778800598a1cbce1815a2ae544589171a0ba7a..ec3f8243841338747d34e55253a41a91a93c5b7e 100644 --- a/sflphone-common/src/observer.h +++ b/sflphone-common/src/observer.h @@ -36,26 +36,29 @@ /** * Observer design pattern interface */ -namespace Pattern { +namespace Pattern +{ /** * Observer interface */ -class Observer { -public: - virtual ~Observer() {}; - virtual void update() = 0; +class Observer +{ + public: + virtual ~Observer() {}; + virtual void update() = 0; }; -class Subject { -public: - virtual ~Subject() {}; - void attach(Observer& observer); - void detach(Observer& observer); - void notify(); +class Subject +{ + public: + virtual ~Subject() {}; + void attach (Observer& observer); + void detach (Observer& observer); + void notify(); -private: - std::list<Observer*> _observers; + private: + std::list<Observer*> _observers; }; } // end namespace diff --git a/sflphone-common/src/plug-in/librarymanager.h b/sflphone-common/src/plug-in/librarymanager.h index 2e94cd5681c3c8dcf7124703ec795ed275eb36e2..eba2ffd2858c267184083e23fc175a314b94acb3 100644 --- a/sflphone-common/src/plug-in/librarymanager.h +++ b/sflphone-common/src/plug-in/librarymanager.h @@ -32,11 +32,12 @@ #define LIBRARY_MANAGER_H #include "dlfcn.h" -#include <stdexcept> +#include <stdexcept> #include "global.h" -class LibraryManager { +class LibraryManager +{ public: typedef void* LibraryHandle; @@ -57,19 +58,22 @@ class LibraryManager { LibraryHandle _handlePtr; }; -class LibraryManagerException : public std::runtime_error { +class LibraryManagerException : public std::runtime_error +{ public: typedef enum Reason { loadingFailed = 0, symbolNotFound - }Reason; + } Reason; LibraryManagerException (const std::string &libraryName, const std::string &details, Reason reason); ~LibraryManagerException (void) throw() {} - inline Reason getReason (void) { return _reason; } + inline Reason getReason (void) { + return _reason; + } const char* what () const throw(); diff --git a/sflphone-common/src/plug-in/plugin.h b/sflphone-common/src/plug-in/plugin.h index 95a9adcb89027954c968a81b75e1b8b88974c368..f3c2afdc9d55e18690977bb99787f88d2d2e583f 100644 --- a/sflphone-common/src/plug-in/plugin.h +++ b/sflphone-common/src/plug-in/plugin.h @@ -32,25 +32,28 @@ #ifndef PLUGIN_H #define PLUGIN_H -#include "global.h" +#include "global.h" -#include "pluginmanager.h" +#include "pluginmanager.h" /* * @file plugin.h - * @brief Define a plugin object + * @brief Define a plugin object */ -class Plugin { +class Plugin +{ public: - Plugin( const std::string &name ){ + Plugin (const std::string &name) { _name = name; } virtual ~Plugin() {} - inline std::string getPluginName (void) { return _name; } + inline std::string getPluginName (void) { + return _name; + } /** * Return the minimal core version required so that the plugin could work @@ -59,7 +62,7 @@ class Plugin { virtual int initFunc (PluginInfo **info) = 0; private: - Plugin &operator =(const Plugin &plugin); + Plugin &operator = (const Plugin &plugin); std::string _name; }; diff --git a/sflphone-common/src/plug-in/pluginmanager.h b/sflphone-common/src/plug-in/pluginmanager.h index a60ee02b3ba86fcb889f1d252ddf709a9437d606..8d322b0b488f6efaee144e3820b6d661a5a690bb 100644 --- a/sflphone-common/src/plug-in/pluginmanager.h +++ b/sflphone-common/src/plug-in/pluginmanager.h @@ -39,9 +39,9 @@ #include "librarymanager.h" #include "global.h" -#include <map> -#include <string> -#include <vector> +#include <map> +#include <string> +#include <vector> class Plugin; @@ -55,7 +55,8 @@ typedef struct PluginInfo { #include "plugin.h" -class PluginManager { +class PluginManager +{ public: /** * Destructor @@ -86,20 +87,20 @@ class PluginManager { bool isPluginLoaded (const std::string &name); int registerPlugin (Plugin *plugin, LibraryManager *library); - + int unregisterPlugin (PluginInfo *plugin); - int deletePlugin (PluginInfo *plugin); + int deletePlugin (PluginInfo *plugin); /** - * Load a unix dynamic/shared library + * Load a unix dynamic/shared library * @param filename The path to the dynamic/shared library * @return LibraryManager* A pointer on the library */ LibraryManager* loadDynamicLibrary (const std::string &filename); /** - * Unload a unix dynamic/shared library + * Unload a unix dynamic/shared library * @param LibraryManager* The pointer on the loaded library */ int unloadDynamicLibrary (LibraryManager* libraryPtr); diff --git a/sflphone-common/src/preferences.cpp b/sflphone-common/src/preferences.cpp new file mode 100644 index 0000000000000000000000000000000000000000..310e214e7f51a7002455abc4868d7ba05781a24d --- /dev/null +++ b/sflphone-common/src/preferences.cpp @@ -0,0 +1,834 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#include "preferences.h" +#include <sstream> +#include "global.h" +#include "user_cfg.h" + +Preferences::Preferences() : _accountOrder ("") + , _audioApi (0) + , _historyLimit (30) + , _historyMaxCalls (20) + , _notifyMails (false) + , _zoneToneChoice (DFT_ZONE) // DFT_ZONE + , _registrationExpire (180) + , _portNum (5060) + , _searchBarDisplay (true) + , _zeroConfenable (false) + , _md5Hash (false) +{ + +} + +Preferences::~Preferences() {} + + +void Preferences::serialize (Conf::YamlEmitter *emiter) +{ + + _debug ("Preference: Serialize configuration"); + + Conf::MappingNode preferencemap (NULL); + + Conf::ScalarNode order (_accountOrder); + std::stringstream audiostr; + audiostr << _audioApi; + Conf::ScalarNode audioapi (audiostr.str()); + std::stringstream histlimitstr; + histlimitstr << _historyLimit; + Conf::ScalarNode historyLimit (histlimitstr.str()); + std::stringstream histmaxstr; + histmaxstr << _historyMaxCalls; + Conf::ScalarNode historyMaxCalls (histmaxstr.str()); + Conf::ScalarNode notifyMails (_notifyMails ? "true" : "false"); + Conf::ScalarNode zoneToneChoice (_zoneToneChoice); + std::stringstream expirestr; + expirestr << _registrationExpire; + Conf::ScalarNode registrationExpire (expirestr.str()); + std::stringstream portstr; + portstr << _portNum; + Conf::ScalarNode portNum (portstr.str()); + Conf::ScalarNode searchBarDisplay (_searchBarDisplay ? "true" : "false"); + Conf::ScalarNode zeroConfenable (_zeroConfenable ? "true" : "false"); + Conf::ScalarNode md5Hash (_md5Hash ? "true" : "false"); + + preferencemap.setKeyValue (orderKey, &order); + preferencemap.setKeyValue (audioApiKey, &audioapi); + preferencemap.setKeyValue (historyLimitKey, &historyLimit); + preferencemap.setKeyValue (historyMaxCallsKey, &historyMaxCalls); + preferencemap.setKeyValue (notifyMailsKey, ¬ifyMails); + preferencemap.setKeyValue (zoneToneChoiceKey, &zoneToneChoice); + preferencemap.setKeyValue (registrationExpireKey, ®istrationExpire); + preferencemap.setKeyValue (portNumKey, &portNum); + preferencemap.setKeyValue (searchBarDisplayKey, &searchBarDisplay); + preferencemap.setKeyValue (zeroConfenableKey, &zeroConfenable); + preferencemap.setKeyValue (md5HashKey, &md5Hash); + + emiter->serializePreference (&preferencemap); +} + +void Preferences::unserialize (Conf::MappingNode *map) +{ + + _debug ("Preference: Unserialize configuration"); + + Conf::ScalarNode *val; + + if (!map) + return; + + val = (Conf::ScalarNode *) (map->getValue (orderKey)); + + if (val) { + _accountOrder = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (audioApiKey)); + + if (val) { + _audioApi = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (historyLimitKey)); + + if (val) { + _historyLimit = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (historyMaxCallsKey)); + + if (val) { + _historyMaxCalls = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (notifyMailsKey)); + + if (val) { + _notifyMails = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (zoneToneChoiceKey)); + + if (val) { + _zoneToneChoice = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (registrationExpireKey)); + + if (val) { + _registrationExpire = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (portNumKey)); + + if (val) { + _portNum = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (searchBarDisplayKey)); + + if (val && !val->getValue().empty()) { + _searchBarDisplay = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (zeroConfenableKey)); + + if (val && !val->getValue().empty()) { + _zeroConfenable = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (md5HashKey)); + + if (val && !val->getValue().empty()) { + _md5Hash = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + + +} + + +VoipPreference::VoipPreference() : _playDtmf (true) + , _playTones (true) + , _pulseLength (atoi (DFT_PULSE_LENGTH_STR)) // DFT_PULSE_LENGTH_STR + , _sendDtmfAs (0) + , _symmetricRtp (true) + , _zidFile (ZRTP_ZIDFILE) // ZRTP_ZID_FILENAME +{ + +} + +VoipPreference::~VoipPreference() {} + + +void VoipPreference::serialize (Conf::YamlEmitter *emitter) +{ + _debug ("VoipPreference: Serialize configuration"); + + Conf::MappingNode preferencemap (NULL); + + Conf::ScalarNode playDtmf (_playDtmf ? "true" : "false"); + Conf::ScalarNode playTones (_playTones ? "true" : "false"); + std::stringstream pulselengthstr; + pulselengthstr << _pulseLength; + Conf::ScalarNode pulseLength (pulselengthstr.str()); + std::stringstream senddtmfstr; + senddtmfstr << _sendDtmfAs; + Conf::ScalarNode sendDtmfAs (senddtmfstr.str()); + Conf::ScalarNode symmetricRtp (_symmetricRtp ? "true" : "false"); + Conf::ScalarNode zidFile (_zidFile.c_str()); + + preferencemap.setKeyValue (playDtmfKey, &playDtmf); + preferencemap.setKeyValue (playTonesKey, &playTones); + preferencemap.setKeyValue (pulseLengthKey, &pulseLength); + preferencemap.setKeyValue (sendDtmfAsKey, &sendDtmfAs); + preferencemap.setKeyValue (symmetricRtpKey, &symmetricRtp); + preferencemap.setKeyValue (zidFileKey, &zidFile); + + emitter->serializeVoipPreference (&preferencemap); +} + +void VoipPreference::unserialize (Conf::MappingNode *map) +{ + + _debug ("VoipPreference: Unserialize configuration"); + + Conf::ScalarNode *val = NULL; + + if (!map) + return; + + val = (Conf::ScalarNode *) (map->getValue (playDtmfKey)); + + if (val && !val->getValue().empty()) { + _playDtmf = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (playTonesKey)); + + if (val && !val->getValue().empty()) { + _playTones = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (pulseLengthKey)); + + if (val) { + _pulseLength = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (sendDtmfAsKey)); + + if (val) { + _sendDtmfAs = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (symmetricRtpKey)); + + if (val && !val->getValue().empty()) { + _symmetricRtp = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (zidFileKey)); + + if (val) { + _zidFile = val->getValue().c_str(); + val = NULL; + } + +} + + + +AddressbookPreference::AddressbookPreference() : _photo (true) + , _enabled (true) + , _list ("") + , _maxResults (25) + , _business (true) + , _home (true) + , _mobile (true) +{ + +} + +AddressbookPreference::~AddressbookPreference() {} + +void AddressbookPreference::serialize (Conf::YamlEmitter *emitter) +{ + _debug ("Addressbook: Serialize configuration"); + + Conf::MappingNode preferencemap (NULL); + + Conf::ScalarNode photo (_photo ? "true" : "false"); + Conf::ScalarNode enabled (_enabled ? "true" : "false"); + Conf::ScalarNode list (_list); + std::stringstream maxresultstr; + maxresultstr << _maxResults; + Conf::ScalarNode maxResults (maxresultstr.str()); + Conf::ScalarNode business (_business ? "true" : "false"); + Conf::ScalarNode home (_home ? "true" : "false"); + Conf::ScalarNode mobile (_mobile ? "true" : "false"); + + preferencemap.setKeyValue (photoKey, &photo); + preferencemap.setKeyValue (enabledKey, &enabled); + preferencemap.setKeyValue (listKey, &list); + preferencemap.setKeyValue (maxResultsKey, &maxResults); + preferencemap.setKeyValue (businessKey, &business); + preferencemap.setKeyValue (homeKey, &home); + preferencemap.setKeyValue (mobileKey, &mobile); + + emitter->serializeAddressbookPreference (&preferencemap); + +} + +void AddressbookPreference::unserialize (Conf::MappingNode *map) +{ + _debug ("Addressbook: Unserialize configuration"); + + Conf::ScalarNode *val = NULL; + + if (!map) + return; + + val = (Conf::ScalarNode *) (map->getValue (photoKey)); + + if (val && ! (val->getValue().empty())) { + _photo = (val->getValue() == "true") ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (enabledKey)); + + if (val && !val->getValue().empty()) { + _enabled = (val->getValue() == "true") ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (listKey)); + + if (val) { + _list = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (maxResultsKey)); + + if (val) { + _maxResults = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (businessKey)); + + if (val && !val->getValue().empty()) { + _business = (val->getValue() == "true") ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (homeKey)); + + if (val && !val->getValue().empty()) { + _home = (val->getValue() == "true") ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (mobileKey)); + + if (val && !val->getValue().empty()) { + _mobile = (val->getValue() == "true") ? true : false; + val = NULL; + } + +} + + +HookPreference::HookPreference() : _iax2Enabled (false) + , _numberAddPrefix ("") + , _numberEnabled (false) + , _sipEnabled (false) + , _urlCommand ("x-www-browser") + , _urlSipField ("X-sflphone-url") +{ + +} + +HookPreference::~HookPreference() {} + +void HookPreference::serialize (Conf::YamlEmitter *emitter) +{ + _debug ("Hook: Serialize configuration"); + + Conf::MappingNode preferencemap (NULL); + + Conf::ScalarNode iax2Enabled (_iax2Enabled ? "true" : "false"); + Conf::ScalarNode numberAddPrefix (_numberAddPrefix); + Conf::ScalarNode numberEnabled (_numberEnabled ? "true" : "false"); + Conf::ScalarNode sipEnabled (_sipEnabled ? "true" : "false"); + Conf::ScalarNode urlCommand (_urlCommand); + Conf::ScalarNode urlSipField (_urlSipField); + + preferencemap.setKeyValue (iax2EnabledKey, &iax2Enabled); + preferencemap.setKeyValue (numberAddPrefixKey, &numberAddPrefix); + preferencemap.setKeyValue (numberEnabledKey, &numberEnabled); + preferencemap.setKeyValue (sipEnabledKey, &sipEnabled); + preferencemap.setKeyValue (urlCommandKey, &urlCommand); + preferencemap.setKeyValue (urlSipFieldKey, &urlSipField); + + emitter->serializeHooksPreference (&preferencemap); +} + +void HookPreference::unserialize (Conf::MappingNode *map) +{ + Conf::ScalarNode *val = NULL; + + _debug ("Hook: Unserialize preference"); + + if (!map) + return; + + val = (Conf::ScalarNode *) (map->getValue (iax2EnabledKey)); + + if (val) { + _iax2Enabled = (val->getValue() == "true") ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (numberAddPrefixKey)); + + if (val) { + _numberAddPrefix = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (numberEnabledKey)); + + if (val) { + _numberEnabled = (val->getValue() == "true") ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (sipEnabledKey)); + + if (val) { + _sipEnabled = (val->getValue() == "true") ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (urlCommandKey)); + + if (val) { + _urlCommand = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (urlSipFieldKey)); + + if (val) { + _urlSipField = val->getValue(); + val = NULL; + } + + +} + + + +AudioPreference::AudioPreference() : _cardin (atoi (ALSA_DFT_CARD)) // ALSA_DFT_CARD + , _cardout (atoi (ALSA_DFT_CARD)) // ALSA_DFT_CARD + , _cardring (atoi (ALSA_DFT_CARD)) // ALSA_DFT_CARD + , _framesize (atoi (DFT_FRAME_SIZE)) // DFT_FRAME_SIZE + , _plugin ("default") // PCM_DEFAULT + , _smplrate (44100) // DFT_SAMPLE_RATE + , _devicePlayback ("") + , _deviceRecord ("") + , _deviceRingtone ("") + , _recordpath ("") // DFT_RECORD_PATH + , _volumemic (atoi (DFT_VOL_SPKR_STR)) // DFT_VOL_SPKR_STR + , _volumespkr (atoi (DFT_VOL_MICRO_STR)) // DFT_VOL_MICRO_STR + , _noisereduce (true) + , _echocancel (true) +{ + +} + +AudioPreference::~AudioPreference() {} + +void AudioPreference::serialize (Conf::YamlEmitter *emitter) +{ + _debug ("AudioPreference: Serialize configuration"); + + Conf::MappingNode preferencemap (NULL); + Conf::MappingNode alsapreferencemap (NULL); + Conf::MappingNode pulsepreferencemap (NULL); + + // alsa preference + std::stringstream instr; + instr << _cardin; + Conf::ScalarNode cardin (instr.str()); // 0 + std::stringstream outstr; + outstr << _cardout; + Conf::ScalarNode cardout (outstr.str()); // 0 + std::stringstream ringstr; + ringstr << _cardring; + Conf::ScalarNode cardring (ringstr.str());// 0 + std::stringstream framestr; + framestr << _framesize; + Conf::ScalarNode framesize (framestr.str()); // 20 + Conf::ScalarNode plugin (_plugin); // default + std::stringstream ratestr; + ratestr << _smplrate; + Conf::ScalarNode smplrate (ratestr.str());// 44100 + + //pulseaudio preference + Conf::ScalarNode devicePlayback (_devicePlayback);//: + Conf::ScalarNode deviceRecord (_deviceRecord); //: + Conf::ScalarNode deviceRingtone (_deviceRingtone); //: + + // general preference + Conf::ScalarNode recordpath (_recordpath); //: /home/msavard/Bureau + std::stringstream micstr; + micstr << _volumemic; + Conf::ScalarNode volumemic (micstr.str()); //: 100 + std::stringstream spkrstr; + spkrstr << _volumespkr; + Conf::ScalarNode volumespkr (spkrstr.str()); //: 100 + Conf::ScalarNode noise (_noisereduce ? "true":"false"); + Conf::ScalarNode echo (_echocancel ? "true":"false"); + + preferencemap.setKeyValue (recordpathKey, &recordpath); + preferencemap.setKeyValue (volumemicKey, &volumemic); + preferencemap.setKeyValue (volumespkrKey, &volumespkr); + + preferencemap.setKeyValue (alsamapKey, &alsapreferencemap); + alsapreferencemap.setKeyValue (cardinKey, &cardin); + alsapreferencemap.setKeyValue (cardoutKey, &cardout); + alsapreferencemap.setKeyValue (cardringKey, &cardring); + alsapreferencemap.setKeyValue (framesizeKey, &framesize); + alsapreferencemap.setKeyValue (pluginKey, &plugin); + alsapreferencemap.setKeyValue (smplrateKey, &smplrate); + + preferencemap.setKeyValue (pulsemapKey, &pulsepreferencemap); + pulsepreferencemap.setKeyValue (devicePlaybackKey, &devicePlayback); + pulsepreferencemap.setKeyValue (deviceRecordKey, &deviceRecord); + pulsepreferencemap.setKeyValue (deviceRingtoneKey, &deviceRingtone); + + preferencemap.setKeyValue (noiseReduceKey, &noise); + preferencemap.setKeyValue (echocancelKey, &echo); + + emitter->serializeAudioPreference (&preferencemap); + +} + +void AudioPreference::unserialize (Conf::MappingNode *map) +{ + _debug ("AudioPreference: Unserialize configuration"); + + if (!map) + return; + + Conf::MappingNode *alsamap = NULL; + Conf::MappingNode *pulsemap = NULL; + + Conf::ScalarNode *val = NULL; + + + val = (Conf::ScalarNode *) (map->getValue (recordpathKey)); + + if (val) { + _recordpath = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (volumemicKey)); + + if (val) { + _volumemic = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (volumespkrKey)); + + if (val) { + _volumespkr = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (noiseReduceKey)); + + if (val) { + _noisereduce = (val->getValue() == "true"); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (echocancelKey)); + + if (val) { + _echocancel = (val->getValue() == "true"); + val = NULL; + } + + alsamap = (Conf::MappingNode *) (map->getValue ("alsa")); + + // did found alsa + if (alsamap) { + + val = (Conf::ScalarNode *) (alsamap->getValue (cardinKey)); + + if (val) { + _cardin = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (alsamap->getValue (cardoutKey)); + + if (val) { + _cardout = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (alsamap->getValue (cardringKey)); + + if (val) { + _cardring = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (alsamap->getValue (framesizeKey)); + + if (val) { + _framesize = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (alsamap->getValue (smplrateKey)); + + if (val) { + _smplrate = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (alsamap->getValue (pluginKey)); + + if (val) { + _plugin = val->getValue(); + val = NULL; + } + + } + + + pulsemap = (Conf::MappingNode *) (map->getValue ("pulse")); + + + if (pulsemap) { + + val = (Conf::ScalarNode *) (pulsemap->getValue (devicePlaybackKey)); + + if (val) { + _devicePlayback = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (pulsemap->getValue (deviceRecordKey)); + + if (val) { + _deviceRecord = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (pulsemap->getValue (deviceRingtoneKey)); + + if (val) { + _deviceRingtone = val->getValue(); + val = NULL; + } + + } + +} + + + +ShortcutPreferences::ShortcutPreferences() : _hangup ("") + , _pickup ("") + , _popup ("") + , _toggleHold ("") + , _togglePickupHangup ("") +{ + +} + +ShortcutPreferences::~ShortcutPreferences() {} + + +std::map<std::string, std::string> ShortcutPreferences::getShortcuts() +{ + + std::map<std::string, std::string> shortcutsMap; + + shortcutsMap.insert (std::pair<std::string, std::string> (hangupShortKey, _hangup)); + shortcutsMap.insert (std::pair<std::string, std::string> (pickupShortKey, _pickup)); + shortcutsMap.insert (std::pair<std::string, std::string> (popupShortKey, _popup)); + shortcutsMap.insert (std::pair<std::string, std::string> (toggleHoldShortKey, _toggleHold)); + shortcutsMap.insert (std::pair<std::string, std::string> (togglePickupHangupShortKey, _togglePickupHangup)); + + return shortcutsMap; +} + + +void ShortcutPreferences::setShortcuts (std::map<std::string, std::string> map_cpy) +{ + // std::map<std::string, int> map_cpy = shortcut; + std::map<std::string, std::string>::iterator it; + + it = map_cpy.find (hangupShortKey); + + if (it != map_cpy.end()) { + _hangup = it->second; + } + + it = map_cpy.find (pickupShortKey); + + if (it != map_cpy.end()) { + _pickup = it->second; + } + + it = map_cpy.find (popupShortKey); + + if (it != map_cpy.end()) { + _popup = it->second; + } + + it = map_cpy.find (toggleHoldShortKey); + + if (it != map_cpy.end()) { + _toggleHold = it->second; + } + + it = map_cpy.find (togglePickupHangupShortKey); + + if (it != map_cpy.end()) { + _togglePickupHangup = it->second; + } + + /* + for (int i = 0; i < (int)shortcutsKeys.size(); i++) { + std::string key = shortcutsKeys.at(i); + it = map_cpy.find(key); + if (it != shortcutsMap.end()) { + Manager::instance().setConfig("Shortcuts", key, it->second); + } + } + */ +} + + +void ShortcutPreferences::serialize (Conf::YamlEmitter *emitter) +{ + + _debug ("ShortcutPreference: Serialize configuration"); + + Conf::MappingNode preferencemap (NULL); + + Conf::ScalarNode hangup (_hangup); + Conf::ScalarNode pickup (_pickup); + Conf::ScalarNode popup (_popup); + Conf::ScalarNode toggleHold (_toggleHold); + Conf::ScalarNode togglePickupHangup (_togglePickupHangup); + + preferencemap.setKeyValue (hangupShortKey, &hangup); + preferencemap.setKeyValue (pickupShortKey, &pickup); + preferencemap.setKeyValue (popupShortKey, &popup); + preferencemap.setKeyValue (toggleHoldShortKey, &toggleHold); + preferencemap.setKeyValue (togglePickupHangupShortKey, &togglePickupHangup); + + emitter->serializeShortcutPreference (&preferencemap); +} + +void ShortcutPreferences::unserialize (Conf::MappingNode *map) +{ + _debug ("ShortcutPreference: Unserialize configuration"); + + if (!map) + return; + + Conf::ScalarNode *val = NULL; + + val = (Conf::ScalarNode *) (map->getValue (hangupShortKey)); + + if (val) { + _hangup = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (pickupShortKey)); + + if (val) { + _pickup = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (popupShortKey)); + + if (val) { + _popup = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (toggleHoldShortKey)); + + if (val) { + _toggleHold = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (togglePickupHangupShortKey)); + + if (val) { + _togglePickupHangup = val->getValue(); + val = NULL; + } +} diff --git a/sflphone-common/src/preferences.h b/sflphone-common/src/preferences.h new file mode 100644 index 0000000000000000000000000000000000000000..eb22c6cc3a1022bac105ac77f4534e058fb2003d --- /dev/null +++ b/sflphone-common/src/preferences.h @@ -0,0 +1,621 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#ifndef __PREFERENCE_H__ +#define __PREFERENCE_H__ + +#include "config/serializable.h" + +// general preferences +const Conf::Key orderKey ("order"); // : 1234/2345/ +const Conf::Key audioApiKey ("audioApi"); // : 0 +const Conf::Key historyLimitKey ("historyLimit"); // : 30 +const Conf::Key historyMaxCallsKey ("historyMaxCalls"); // : 20 +const Conf::Key notifyMailsKey ("notifyMails"); // : false +const Conf::Key zoneToneChoiceKey ("zoneToneChoice"); // : North America +const Conf::Key registrationExpireKey ("registrationExpire");// : 180 +const Conf::Key portNumKey ("portNum"); // : 5060 +const Conf::Key searchBarDisplayKey ("searchBarDisplay"); // : true +const Conf::Key zeroConfenableKey ("zeroConfenable"); // : false +const Conf::Key md5HashKey ("md5Hash"); // : false + +// voip preferences +const Conf::Key playDtmfKey ("playDtmf"); // true true +const Conf::Key playTonesKey ("playTones"); // true +const Conf::Key pulseLengthKey ("pulseLength"); //=250 +const Conf::Key sendDtmfAsKey ("sendDtmfAs");// =0 +const Conf::Key symmetricRtpKey ("symmetric");// =true +const Conf::Key zidFileKey ("zidFile");// =sfl.zid + +// addressbook preferences +const Conf::Key photoKey ("photo");// false +const Conf::Key enabledKey ("enabled");// true +const Conf::Key listKey ("list");// 1243608768.30329.0@emilou-desktop/1243456917.15690.23@emilou-desktop/ +const Conf::Key maxResultsKey ("maxResults");// 25 +const Conf::Key businessKey ("business");// true +const Conf::Key homeKey ("home");// false +const Conf::Key mobileKey ("mobile");// false + +// hooks preferences +const Conf::Key iax2EnabledKey ("iax2Enabled");// : false +const Conf::Key numberAddPrefixKey ("numberAddPrefix");//: false +const Conf::Key numberEnabledKey ("numberEnabled"); //: false +const Conf::Key sipEnabledKey ("sipEnabled"); //: false +const Conf::Key urlCommandKey ("urlCommand"); //: x-www-browser +const Conf::Key urlSipFieldKey ("urlSipField"); //: X-sflphone-url + +// audio preferences +const Conf::Key alsamapKey ("alsa"); +const Conf::Key pulsemapKey ("pulse"); +const Conf::Key cardinKey ("cardin");// : 0 +const Conf::Key cardoutKey ("cardout");// 0 +const Conf::Key cardringKey ("cardring");// : 0 +const Conf::Key framesizeKey ("framesize");// : 20 +const Conf::Key pluginKey ("plugin"); //: default +const Conf::Key smplrateKey ("smplrate");//: 44100 +const Conf::Key devicePlaybackKey ("devicePlayback");//: +const Conf::Key deviceRecordKey ("deviceRecord");// : +const Conf::Key deviceRingtoneKey ("deviceRingtone");// : +const Conf::Key recordpathKey ("recordpath");//: /home/msavard/Bureau +const Conf::Key volumemicKey ("volumemic");//: 100 +const Conf::Key volumespkrKey ("volumespkr");//: 100 +const Conf::Key noiseReduceKey ("noiseReduce"); +const Conf::Key echocancelKey ("echocancel"); + + +// shortcut preferences +const Conf::Key hangupShortKey ("hangUp"); +const Conf::Key pickupShortKey ("pickUp"); +const Conf::Key popupShortKey ("popupWindow"); +const Conf::Key toggleHoldShortKey ("toggleHold"); +const Conf::Key togglePickupHangupShortKey ("togglePickupHangup"); + + +class Preferences : public Serializable +{ + + public: + + Preferences(); + + ~Preferences(); + + virtual void serialize (Conf::YamlEmitter *emitter); + + virtual void unserialize (Conf::MappingNode *map); + + + std::string getAccountOrder (void) { + return _accountOrder; + } + void setAccountOrder (std::string ord) { + _accountOrder = ord; + } + + int getAudioApi (void) { + return _audioApi; + } + void setAudioApi (int api) { + _audioApi = api; + } + + int getHistoryLimit (void) { + return _historyLimit; + } + void setHistoryLimit (int lim) { + _historyLimit = lim; + } + + int getHistoryMaxCalls (void) { + return _historyMaxCalls; + } + void setHistoryMaxCalls (int max) { + _historyMaxCalls = max; + } + + bool getNotifyMails (void) { + return _notifyMails; + } + void setNotifyMails (bool mails) { + _notifyMails = mails; + } + + std::string getZoneToneChoice (void) { + return _zoneToneChoice; + } + void setZoneToneChoice (std::string str) { + _zoneToneChoice = str; + } + + int getRegistrationExpire (void) { + return _registrationExpire; + } + void setRegistrationExpire (int exp) { + _registrationExpire = exp; + } + + int getPortNum (void) { + return _portNum; + } + void setPortNum (int port) { + _portNum = port; + } + + bool getSearchBarDisplay (void) { + return _searchBarDisplay; + } + void setSearchBarDisplay (bool search) { + _searchBarDisplay = search; + } + + bool getZeroConfenable (void) { + return _zeroConfenable; + } + void setZeroConfenable (bool enable) { + _zeroConfenable = enable; + } + + bool getMd5Hash (void) { + return _md5Hash; + } + void setMd5Hash (bool md5) { + _md5Hash = md5; + } + + private: + + // account order + std::string _accountOrder; + + int _audioApi; + int _historyLimit; + int _historyMaxCalls; + bool _notifyMails; + std::string _zoneToneChoice; + int _registrationExpire; + int _portNum; + bool _searchBarDisplay; + bool _zeroConfenable; + bool _md5Hash; + +}; + + +class VoipPreference : public Serializable +{ + + public: + + VoipPreference(); + + ~VoipPreference(); + + virtual void serialize (Conf::YamlEmitter *emitter); + + virtual void unserialize (Conf::MappingNode *map); + + bool getPlayDtmf (void) { + return _playDtmf; + } + void setPlayDtmf (bool dtmf) { + _playDtmf = dtmf; + } + + bool getPlayTones (void) { + return _playTones; + } + void setPlayTones (bool tone) { + _playTones = tone; + } + + int getPulseLength (void) { + return _pulseLength; + } + void setPulseLength (int length) { + _pulseLength = length; + } + + int getSendDtmfAs (void) { + return _sendDtmfAs; + } + void setSendDtmfAs (int dtmf) { + _sendDtmfAs = dtmf; + } + + bool getSymmetricRtp (void) { + return _symmetricRtp; + } + void setSymmetricRtp (bool sym) { + _symmetricRtp = sym; + } + + std::string getZidFile (void) { + return _zidFile; + } + void setZidFile (std::string file) { + _zidFile = file; + } + + private: + + bool _playDtmf; + bool _playTones; + int _pulseLength; + int _sendDtmfAs; + bool _symmetricRtp; + std::string _zidFile; + +}; + +class AddressbookPreference : public Serializable +{ + + public: + + AddressbookPreference(); + + ~AddressbookPreference(); + + virtual void serialize (Conf::YamlEmitter *emitter); + + virtual void unserialize (Conf::MappingNode *map); + + bool getPhoto (void) { + return _photo; + } + void setPhoto (bool p) { + _photo = p; + } + + bool getEnabled (void) { + return _enabled; + } + void setEnabled (bool e) { + _enabled = e; + } + + std::string getList (void) { + return _list; + } + void setList (std::string l) { + _list = l; + } + + int getMaxResults (void) { + return _maxResults; + } + void setMaxResults (int r) { + _maxResults = r; + } + + bool getBusiness (void) { + return _business; + } + void setBusiness (bool b) { + _business = b; + } + + bool getHome (void) { + return _home; + } + void setHone (bool h) { + _home = h; + } + + bool getMobile (void) { + return _mobile; + } + void setMobile (bool m) { + _mobile = m; + } + + private: + + bool _photo; + bool _enabled; + std::string _list; + int _maxResults; + bool _business; + bool _home; + bool _mobile; + +}; + + +class HookPreference : public Serializable +{ + + public: + + HookPreference(); + + ~HookPreference(); + + virtual void serialize (Conf::YamlEmitter *emitter); + + virtual void unserialize (Conf::MappingNode *map); + + bool getIax2Enabled (void) { + return _iax2Enabled; + } + void setIax2Enabled (bool i) { + _iax2Enabled = i; + } + + std::string getNumberAddPrefix (void) { + return _numberAddPrefix; + } + void setNumberAddPrefix (std::string n) { + _numberAddPrefix = n; + } + + bool getNumberEnabled (void) { + return _numberEnabled; + } + void setNumberEnabled (bool n) { + _numberEnabled = n; + } + + bool getSipEnabled (void) { + return _sipEnabled; + } + void setSipEnabled (bool s) { + _sipEnabled = s; + } + + std::string getUrlCommand (void) { + return _urlCommand; + } + void setUrlCommand (std::string u) { + _urlCommand = u; + } + + std::string getUrlSipField (void) { + return _urlSipField; + } + void setUrlSipField (std::string u) { + _urlSipField = u; + } + + private: + + bool _iax2Enabled;// : false + std::string _numberAddPrefix;//: false + bool _numberEnabled; //: false + bool _sipEnabled; //: false + std::string _urlCommand; //: x-www-browser + std::string _urlSipField; //: X-sflphone-url + +}; + + +class AudioPreference : public Serializable +{ + + public: + + AudioPreference(); + + ~AudioPreference(); + + virtual void serialize (Conf::YamlEmitter *emitter); + + virtual void unserialize (Conf::MappingNode *map); + + // alsa preference + int getCardin (void) { + return _cardin; + } + void setCardin (int c) { + _cardin = c; + } + + int getCardout (void) { + return _cardout; + } + void setCardout (int c) { + _cardout = c; + } + + int getCardring (void) { + return _cardring; + } + void setCardring (int c) { + _cardring = c; + } + + int getFramesize (void) { + return _framesize; + } + void setFramesize (int f) { + _framesize = f; + } + + std::string getPlugin (void) { + return _plugin; + } + void setPlugin (std::string p) { + _plugin = p; + } + + int getSmplrate (void) { + return _smplrate; + } + void setSmplrate (int r) { + _smplrate = r; + } + + //pulseaudio preference + std::string getDevicePlayback (void) { + return _devicePlayback; + } + void setDevicePlayback (std::string p) { + _devicePlayback = p; + } + + std::string getDeviceRecord (void) { + return _deviceRecord; + } + void setDeviceRecord (std::string r) { + _deviceRecord = r; + } + + std::string getDeviceRingtone (void) { + return _deviceRingtone; + } + void setDeviceRingtone (std::string r) { + _deviceRingtone = r; + } + + // general preference + std::string getRecordpath (void) { + return _recordpath; + } + void setRecordpath (std::string r) { + _recordpath = r; + } + + int getVolumemic (void) { + return _volumemic; + } + void setVolumemic (int m) { + _volumemic = m; + } + + int getVolumespkr (void) { + return _volumespkr; + } + void setVolumespkr (int s) { + _volumespkr = s; + } + + bool getNoiseReduce (void) { + return _noisereduce; + } + + void setNoiseReduce (bool noise) { + _noisereduce = noise; + } + + bool getEchoCancel (void) { + return _echocancel; + } + + void setEchoCancel (bool echo) { + _echocancel = echo; + } + + private: + + // alsa preference + int _cardin; // 0 + int _cardout; // 0 + int _cardring;// 0 + int _framesize; // 20 + std::string _plugin; // default + int _smplrate;// 44100 + + //pulseaudio preference + std::string _devicePlayback;//: + std::string _deviceRecord; //: + std::string _deviceRingtone; //: + + // general preference + std::string _recordpath; //: /home/msavard/Bureau + int _volumemic; //: 100 + int _volumespkr; //: 100 + + bool _noisereduce; + bool _echocancel; +}; + + +class ShortcutPreferences : public Serializable +{ + + public: + + ShortcutPreferences(); + + ~ShortcutPreferences(); + + virtual void serialize (Conf::YamlEmitter *emitter); + + virtual void unserialize (Conf::MappingNode *map); + + void setShortcuts (std::map<std::string, std::string> shortcut); + std::map<std::string, std::string> getShortcuts (void); + + std::string getHangup (void) { + return _hangup; + } + void setHangup (std::string hangup) { + _hangup = hangup; + } + + std::string getPickup (void) { + return _pickup; + } + void setPickup (std::string pickup) { + _pickup = pickup; + } + + std::string getPopup (void) { + return _popup; + } + void setPopup (std::string popup) { + _popup = popup; + } + + std::string getToggleHold (void) { + return _toggleHold; + } + void setToggleHold (std::string hold) { + _toggleHold = hold; + } + + std::string getTogglePickupHangup (void) { + return _togglePickupHangup; + } + void setTogglePickupHangup (std::string toggle) { + _togglePickupHangup = toggle; + } + + private: + + std::string _hangup; + std::string _pickup; + std::string _popup; + std::string _toggleHold; + std::string _togglePickupHangup; + +}; + +#endif diff --git a/sflphone-common/src/sip/Pattern.h b/sflphone-common/src/sip/Pattern.h index a929c655218825eecc3a9f22634731d6712c6cbe..8d515a64589bf8a0a0bf6cb413d1800275736fab 100644 --- a/sflphone-common/src/sip/Pattern.h +++ b/sflphone-common/src/sip/Pattern.h @@ -10,7 +10,7 @@ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -34,314 +34,318 @@ #include <vector> #include <pcre.h> -namespace sfl { - - /** - * Exception object that is thrown when - * an error occured while compiling the - * regular expression. - */ - class compile_error : public std::invalid_argument - { - public: - explicit compile_error(const std::string& error) : - std::invalid_argument(error) {} - }; - - /** - * Exception object that is thrown when - * an error occured while mathing a - * pattern to an expression. - */ - class match_error : public std::invalid_argument - { - public: - match_error(const std::string& error) : - std::invalid_argument(error) {} - }; - - /** - * This class implements in its way - * some of the libpcre library. - */ - - class Pattern { - - public: - +namespace sfl +{ + +/** + * Exception object that is thrown when + * an error occured while compiling the + * regular expression. + */ +class compile_error : public std::invalid_argument +{ + public: + explicit compile_error (const std::string& error) : + std::invalid_argument (error) {} +}; + +/** + * Exception object that is thrown when + * an error occured while mathing a + * pattern to an expression. + */ +class match_error : public std::invalid_argument +{ + public: + match_error (const std::string& error) : + std::invalid_argument (error) {} +}; + +/** +* This class implements in its way +* some of the libpcre library. +*/ + +class Pattern +{ + + public: + + /** + * Constructor for a regular expression + * pattern evaluator/matcher. + * + * @param pattern + * The regular expression to + * be used for this instance. + */ + + Pattern (const std::string& pattern, + const std::string& options = ""); + + /** + * Destructor. Pcre pattern gets freed + * here. + */ + ~Pattern(); + + /** + * Assignment operator overloading. + * Set the regular expression + * to be used on subject strings + * and compile the regular expression + * from that string. + * + * @param pattern The new pattern + */ + void operator= (const std::string& pattern) { + _pattern = pattern; + compile(); + } + + void operator= (const char * pattern) { + _pattern = pattern; + compile(); + } + + /** + * Compile the regular expression + * from the pattern that was set for + * this object. + */ + void compile (void); + + /** + * Get the currently set regular expression + * that is used on subject strings + * + * @return The currently set pattern + */ + inline std::string getPattern (void) { + return _pattern; + } + + /** + * << operator overload. Sets the the subject + * for latter use on the >> operator. + * + * @param subject + * The expression to be evaluated + * by the pattern. + * + */ + void operator<< (const std::string& subject) { + _subject = subject; + } + + /** + * Get the start position of the overall match. + * + * @return the start position of the overall match. + */ + size_t start (void) const; + + /** + * Get the start position of the specified match. + * + * @param groupNumber The capturing group number. + * + * @return the start position of the specified match. + */ + size_t start (unsigned int groupNumber) const; + + /** + * Get the start position of the specified match. + * + * @param groupName The capturing group name. + */ + void start (const std::string& groupName) const; + + /** + * Get the end position of the overall match. + * + * @return the end position of the overall match. + */ + size_t end (void) const; + + /** + * Get the end position of the specified match. + * + * @param groupNumber The capturing group number. + * + * @return the end position of the specified match. + */ + size_t end (unsigned int groupNumber) const; + + /** + * Get the end position of the specified match. + * + * @param groupName The capturing group name. + * + * @return the end position of the specified match. + */ + void end (const std::string& groupName) const; + + /** + * Get the number of capturing groups in the + * compiled regex. + * + * @return The number of capture groups. + * + * @pre The regular expression should have been + * compiled prior to the execution of this method. + */ + unsigned int getCaptureGroupCount (void); + + /** + * Get the substring matched in a capturing + * group (named or unnamed). + * + * This methods only performs a basic lookup + * inside its internal substring table. Thus, + * matches() should have been called prior to + * this method in order to obtain the desired + * output. + * + * @param groupName The name of the group + * + * @return the substring matched by the + * regular expression designated + * the group name. + */ + std::string group (const std::string& groupName); + + /** + * Get the substring matched in a named group. + * + * This methods only performs a basic lookup + * inside its internal substring table. Thus, + * matches() should have been called prior to + * this method in order to obtain the desired + * output. + * + * @param groupNumber The number of the group. + * + * @return the substring matched by the + * regular expression designated + * the group number. + */ + std::string group (int groupNumber); + + /** + * Similar to python's MatchObject.groups. Get all + * the substrings matched by the capture groups defined + * in the pattern. The complete (implicit) capture group + * is not returned : ie only groups from 1 up to the number + * of groups in the pattern are returned. + * + * @return A vector of stings that were matched by some + * capturing group in the pattern. + * + * @pre The regular expression should have been + * compiled prior to the execution of this method. + */ + std::vector<std::string> groups (void); + + /** + * Try to match the compiled pattern with a + * subject. + * + * @param subject Subject to be matched + * by the pattern. + * + * @return true If the subject matches the pattern, + * false otherwise. + * + * @pre The regular expression should have been + * compiled prior to the execution of this method. + * + * @post The internal substring table will be updated + * with the new matches. Therefore, subsequent + * calls to group may return different results. + */ + bool matches (const std::string& subject) throw (match_error); + + /** + * Try to match the compiled pattern with the implicit + * subject. + * + * @return true If the subject matches the pattern, + * false otherwise. + * + * @pre The regular expression should have been + * compiled prior to the execution of this method. + * + * @post The internal substring table will be updated + * with the new matches. Therefore, subsequent + * calls to group may return different results. + */ + bool matches (void) throw (match_error); + + /** + * Split the subject into a list of substrings. + * + * @return A vector of substrings. + * + * @pre The regular expression should have been + * compiled prior to the execution of this method. + * + * @post The internal subject won't be affected by this + * by this operation. In other words: subject_before = + * subject_after. + */ + std::vector<std::string> split (void); // throw(match_error); + + private: + /** + * The regular expression that represents that pattern. + */ + std::string _pattern; + + /** + * The optional subject string. + */ + std::string _subject; + + /** + * PCRE struct that + * contains the compiled regular + * expression + */ + pcre * _re; + + /** + * The internal output vector used by PCRE. + */ + int * _ovector; + + /** + * The size of the _ovector + */ + int _ovectorSize; + + /** + * Current offset in the _ovector; + */ + + int _offset[2]; + + /** + * The number of substrings matched after calling + * pcre_exec. + */ + int _count; + + /** + * PCRE options for this pattern. + */ + int _options; + /** - * Constructor for a regular expression - * pattern evaluator/matcher. - * - * @param pattern - * The regular expression to - * be used for this instance. - */ - - Pattern(const std::string& pattern, - const std::string& options = ""); - - /** - * Destructor. Pcre pattern gets freed - * here. - */ - ~Pattern(); - - /** - * Assignment operator overloading. - * Set the regular expression - * to be used on subject strings - * and compile the regular expression - * from that string. - * - * @param pattern The new pattern - */ - void operator=(const std::string& pattern) { - _pattern = pattern; - compile(); - } - - void operator=(const char * pattern) { - _pattern = pattern; - compile(); - } - - /** - * Compile the regular expression - * from the pattern that was set for - * this object. - */ - void compile(void); - - /** - * Get the currently set regular expression - * that is used on subject strings - * - * @return The currently set pattern - */ - inline std::string getPattern(void) { return _pattern; } - - /** - * << operator overload. Sets the the subject - * for latter use on the >> operator. - * - * @param subject - * The expression to be evaluated - * by the pattern. - * - */ - void operator<<(const std::string& subject) { - _subject = subject; - } - - /** - * Get the start position of the overall match. - * - * @return the start position of the overall match. - */ - size_t start(void) const; - - /** - * Get the start position of the specified match. - * - * @param groupNumber The capturing group number. - * - * @return the start position of the specified match. - */ - size_t start(unsigned int groupNumber) const; - - /** - * Get the start position of the specified match. - * - * @param groupName The capturing group name. - */ - void start(const std::string& groupName) const; - - /** - * Get the end position of the overall match. - * - * @return the end position of the overall match. - */ - size_t end(void) const; - - /** - * Get the end position of the specified match. - * - * @param groupNumber The capturing group number. - * - * @return the end position of the specified match. - */ - size_t end(unsigned int groupNumber) const; - - /** - * Get the end position of the specified match. - * - * @param groupName The capturing group name. - * - * @return the end position of the specified match. - */ - void end(const std::string& groupName) const; - - /** - * Get the number of capturing groups in the - * compiled regex. - * - * @return The number of capture groups. - * - * @pre The regular expression should have been - * compiled prior to the execution of this method. - */ - unsigned int getCaptureGroupCount(void); - - /** - * Get the substring matched in a capturing - * group (named or unnamed). - * - * This methods only performs a basic lookup - * inside its internal substring table. Thus, - * matches() should have been called prior to - * this method in order to obtain the desired - * output. - * - * @param groupName The name of the group - * - * @return the substring matched by the - * regular expression designated - * the group name. - */ - std::string group(const std::string& groupName); - - /** - * Get the substring matched in a named group. - * - * This methods only performs a basic lookup - * inside its internal substring table. Thus, - * matches() should have been called prior to - * this method in order to obtain the desired - * output. - * - * @param groupNumber The number of the group. - * - * @return the substring matched by the - * regular expression designated - * the group number. - */ - std::string group(int groupNumber); - - /** - * Similar to python's MatchObject.groups. Get all - * the substrings matched by the capture groups defined - * in the pattern. The complete (implicit) capture group - * is not returned : ie only groups from 1 up to the number - * of groups in the pattern are returned. - * - * @return A vector of stings that were matched by some - * capturing group in the pattern. - * - * @pre The regular expression should have been - * compiled prior to the execution of this method. - */ - std::vector<std::string> groups(void); - - /** - * Try to match the compiled pattern with a - * subject. - * - * @param subject Subject to be matched - * by the pattern. - * - * @return true If the subject matches the pattern, - * false otherwise. - * - * @pre The regular expression should have been - * compiled prior to the execution of this method. - * - * @post The internal substring table will be updated - * with the new matches. Therefore, subsequent - * calls to group may return different results. - */ - bool matches(const std::string& subject) throw(match_error); - - /** - * Try to match the compiled pattern with the implicit - * subject. - * - * @return true If the subject matches the pattern, - * false otherwise. - * - * @pre The regular expression should have been - * compiled prior to the execution of this method. - * - * @post The internal substring table will be updated - * with the new matches. Therefore, subsequent - * calls to group may return different results. - */ - bool matches(void) throw(match_error); - - /** - * Split the subject into a list of substrings. - * - * @return A vector of substrings. - * - * @pre The regular expression should have been - * compiled prior to the execution of this method. - * - * @post The internal subject won't be affected by this - * by this operation. In other words: subject_before = - * subject_after. - */ - std::vector<std::string> split(void); // throw(match_error); - - private: - /** - * The regular expression that represents that pattern. - */ - std::string _pattern; - - /** - * The optional subject string. - */ - std::string _subject; - - /** - * PCRE struct that - * contains the compiled regular - * expression - */ - pcre * _re; - - /** - * The internal output vector used by PCRE. - */ - int * _ovector; - - /** - * The size of the _ovector - */ - int _ovectorSize; - - /** - * Current offset in the _ovector; - */ - - int _offset[2]; - - /** - * The number of substrings matched after calling - * pcre_exec. - */ - int _count; - - /** - * PCRE options for this pattern. - */ - int _options; - - /** - * String representation of the options. - */ - std::string _optionsDescription; - }; + * String representation of the options. + */ + std::string _optionsDescription; +}; } diff --git a/sflphone-common/src/sip/SdesNegotiator.h b/sflphone-common/src/sip/SdesNegotiator.h index b57b46a16354e2582cdd60f32e23f9298414f676..1f11324be039ad70e9485d4c2487c74741af5c6a 100644 --- a/sflphone-common/src/sip/SdesNegotiator.h +++ b/sflphone-common/src/sip/SdesNegotiator.h @@ -11,7 +11,7 @@ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -31,189 +31,218 @@ #define __SFL_SDES_NEGOTIATOR_H__ #include <stdexcept> -#include <string> +#include <string> #include <vector> -namespace sfl { - - /** - * General exception object that is thrown when - * an error occured with a regular expression - * operation. - */ - class parse_error : public std::invalid_argument - { - public: - explicit parse_error(const std::string& error) : - std::invalid_argument(error) {} - }; - - enum CipherMode { - AESCounterMode, - AESF8Mode - }; - - enum MACMode { - HMACSHA1 - }; - - enum KeyMethod { - Inline - // url, maybe at some point - }; - - struct CryptoSuiteDefinition { - char * name; - int masterKeyLength; - int masterSaltLength; - int srtpLifetime; - int srtcpLifetime; - CipherMode cipher; - int encryptionKeyLength; - MACMode mac; - int srtpAuthTagLength; - int srtcpAuthTagLength; - int srtpAuthKeyLength; - int srtcpAuthKeyLen; - }; - - /** - * List of accepted Crypto-Suites - * as defined in RFC4568 (6.2) - */ - const CryptoSuiteDefinition CryptoSuites[3] = { - {(char*)"AES_CM_128_HMAC_SHA1_80", 128, 112, 48, 31, AESCounterMode, 128, HMACSHA1, 80, 80, 160, 160 }, - {(char*)"AES_CM_128_HMAC_SHA1_32", 128, 112, 48, 31, AESCounterMode, 128, HMACSHA1, 32, 80, 160, 160 }, - {(char*)"F8_128_HMAC_SHA1_80", 128, 112, 48, 31, AESF8Mode, 128, HMACSHA1, 80, 80, 160, 160 } }; - - - class CryptoAttribute { - +namespace sfl +{ + +/** + * General exception object that is thrown when + * an error occured with a regular expression + * operation. + */ +class parse_error : public std::invalid_argument +{ public: - CryptoAttribute(std::string tag, - std::string cryptoSuite, - std::string srtpKeyMethod, - std::string srtpKeyInfo, - std::string lifetime, - std::string mkiValue, - std::string mkiLength) : - tag(tag), - cryptoSuite(cryptoSuite), - srtpKeyMethod(srtpKeyMethod), - srtpKeyInfo(srtpKeyInfo), - lifetime(lifetime), - mkiValue(mkiValue), - mkiLength(mkiLength) {}; - - - inline std::string getTag() { return tag; }; - inline std::string getCryptoSuite() { return cryptoSuite; }; - inline std::string getSrtpKeyMethod() { return srtpKeyMethod; }; - inline std::string getSrtpKeyInfo() { return srtpKeyInfo; }; - inline std::string getLifetime() { return lifetime; }; - inline std::string getMkiValue() { return mkiValue; }; - inline std::string getMkiLength() { return mkiLength; }; - - private: - std::string tag; - std::string cryptoSuite; - std::string srtpKeyMethod; - std::string srtpKeyInfo; - std::string lifetime; - std::string mkiValue; - std::string mkiLength; - }; - - class SdesNegotiator - { + explicit parse_error (const std::string& error) : + std::invalid_argument (error) {} +}; + +enum CipherMode { + AESCounterMode, + AESF8Mode +}; + +enum MACMode { + HMACSHA1 +}; + +enum KeyMethod { + Inline + // url, maybe at some point +}; + +struct CryptoSuiteDefinition { + char * name; + int masterKeyLength; + int masterSaltLength; + int srtpLifetime; + int srtcpLifetime; + CipherMode cipher; + int encryptionKeyLength; + MACMode mac; + int srtpAuthTagLength; + int srtcpAuthTagLength; + int srtpAuthKeyLength; + int srtcpAuthKeyLen; +}; + +/** +* List of accepted Crypto-Suites +* as defined in RFC4568 (6.2) +*/ +const CryptoSuiteDefinition CryptoSuites[3] = { + { (char*) "AES_CM_128_HMAC_SHA1_80", 128, 112, 48, 31, AESCounterMode, 128, HMACSHA1, 80, 80, 160, 160 }, + { (char*) "AES_CM_128_HMAC_SHA1_32", 128, 112, 48, 31, AESCounterMode, 128, HMACSHA1, 32, 80, 160, 160 }, + { (char*) "F8_128_HMAC_SHA1_80", 128, 112, 48, 31, AESF8Mode, 128, HMACSHA1, 80, 80, 160, 160 } +}; + + +class CryptoAttribute +{ + + public: + CryptoAttribute (std::string tag, + std::string cryptoSuite, + std::string srtpKeyMethod, + std::string srtpKeyInfo, + std::string lifetime, + std::string mkiValue, + std::string mkiLength) : + tag (tag), + cryptoSuite (cryptoSuite), + srtpKeyMethod (srtpKeyMethod), + srtpKeyInfo (srtpKeyInfo), + lifetime (lifetime), + mkiValue (mkiValue), + mkiLength (mkiLength) {}; + + + inline std::string getTag() { + return tag; + }; + inline std::string getCryptoSuite() { + return cryptoSuite; + }; + inline std::string getSrtpKeyMethod() { + return srtpKeyMethod; + }; + inline std::string getSrtpKeyInfo() { + return srtpKeyInfo; + }; + inline std::string getLifetime() { + return lifetime; + }; + inline std::string getMkiValue() { + return mkiValue; + }; + inline std::string getMkiLength() { + return mkiLength; + }; + + private: + std::string tag; + std::string cryptoSuite; + std::string srtpKeyMethod; + std::string srtpKeyInfo; + std::string lifetime; + std::string mkiValue; + std::string mkiLength; +}; + +class SdesNegotiator +{ /** * Constructor for an SDES crypto attributes - * negotiator. + * negotiator. * - * @param attribute - * A vector of crypto attributes as defined in + * @param attribute + * A vector of crypto attributes as defined in * RFC4568. This string will be parsed * and a crypto context will be created - * from it. + * from it. + */ + + public: + SdesNegotiator (const std::vector<CryptoSuiteDefinition>& localCapabilites, const std::vector<std::string>& remoteAttribute); + ~SdesNegotiator() { }; + + bool negotiate (void); + + /** + * Return crypto suite after negotiation + */ + std::string getCryptoSuite (void) { + return _cryptoSuite; + } + + /** + * Return key method after negotiation (most likely inline:) + */ + std::string getKeyMethod (void) { + return _srtpKeyMethod; + } + + /** + * Return crypto suite after negotiation + */ + std::string getKeyInfo (void) { + return _srtpKeyInfo; + } + + /** + * Return key lifetime after negotiation + */ + std::string getLifeTime (void) { + return _lifetime; + } + + /** + * Return mki value after negotiation + */ + std::string getMkiValue (void) { + return _mkiValue; + } + + /** + * Return mki length after negotiation + */ + std::string getMkiLength (void) { + return _mkiLength; + } + + private: + /** + * A vector list containing the remote attributes. + * Multiple crypto lines can be sent, and the + * prefered method is then chosen from that list. + */ + std::vector<std::string> _remoteAttribute; + + std::vector<CryptoSuiteDefinition> _localCapabilities; + + /** + * Selected crypto suite after negotiation + */ + std::string _cryptoSuite; + + /** + * Selected key method after negotiation (most likely inline:) + */ + std::string _srtpKeyMethod; + + /** + * Selected crypto suite after negotiation + */ + std::string _srtpKeyInfo; + + /** + * Selected key lifetime after negotiation */ - - public: - SdesNegotiator(const std::vector<CryptoSuiteDefinition>& localCapabilites, const std::vector<std::string>& remoteAttribute); - ~SdesNegotiator() { }; - - bool negotiate(void); - - /** - * Return crypto suite after negotiation - */ - std::string getCryptoSuite(void) { return _cryptoSuite; } - - /** - * Return key method after negotiation (most likely inline:) - */ - std::string getKeyMethod(void) { return _srtpKeyMethod; } - - /** - * Return crypto suite after negotiation - */ - std::string getKeyInfo(void) { return _srtpKeyInfo; } - - /** - * Return key lifetime after negotiation - */ - std::string getLifeTime(void) { return _lifetime; } - - /** - * Return mki value after negotiation - */ - std::string getMkiValue(void) { return _mkiValue; } - - /** - * Return mki length after negotiation - */ - std::string getMkiLength(void) { return _mkiLength; } - - private: - /** - * A vector list containing the remote attributes. - * Multiple crypto lines can be sent, and the - * prefered method is then chosen from that list. - */ - std::vector<std::string> _remoteAttribute; - - std::vector<CryptoSuiteDefinition> _localCapabilities; - - /** - * Selected crypto suite after negotiation - */ - std::string _cryptoSuite; - - /** - * Selected key method after negotiation (most likely inline:) - */ - std::string _srtpKeyMethod; - - /** - * Selected crypto suite after negotiation - */ - std::string _srtpKeyInfo; - - /** - * Selected key lifetime after negotiation - */ - std::string _lifetime; - - /** - * Selected mki value after negotiation - */ - std::string _mkiValue; - - /** - * Selected mki length after negotiation - */ - std::string _mkiLength; - - std::vector<CryptoAttribute *> parse(void); - }; + std::string _lifetime; + + /** + * Selected mki value after negotiation + */ + std::string _mkiValue; + + /** + * Selected mki length after negotiation + */ + std::string _mkiLength; + + std::vector<CryptoAttribute *> parse (void); +}; } #endif diff --git a/sflphone-common/src/sip/im/InstantMessaging.cpp b/sflphone-common/src/sip/im/InstantMessaging.cpp index a3e253af8f96c56b29c0aceea03c080102b32702..d44acfdff140df5b451d8c2f8c6736edfa1690a0 100644 --- a/sflphone-common/src/sip/im/InstantMessaging.cpp +++ b/sflphone-common/src/sip/im/InstantMessaging.cpp @@ -5,7 +5,7 @@ namespace sfl InstantMessaging::InstantMessaging() : imFiles () - , messageMaxSize(MAXIMUM_MESSAGE_LENGTH) {} + , messageMaxSize (MAXIMUM_MESSAGE_LENGTH) {} InstantMessaging::~InstantMessaging() {} @@ -140,8 +140,8 @@ pj_status_t InstantMessaging::send_message (pjsip_inv_session *session, CallID& int size = multiple_messages.size(); int i = 0; - // Maximum is above 1500 character - // TODO: Send every messages + // Maximum is above 1500 character + // TODO: Send every messages send (session, id, multiple_messages[i]); } diff --git a/sflphone-common/src/sip/im/InstantMessaging.h b/sflphone-common/src/sip/im/InstantMessaging.h index 4277b354562d732bc11d9b059d32d0eb69a6dd2a..bcc25d85c11dbeb6577ea2d574e99fb7b78bacb1 100644 --- a/sflphone-common/src/sip/im/InstantMessaging.h +++ b/sflphone-common/src/sip/im/InstantMessaging.h @@ -17,131 +17,123 @@ #define STR_PLAIN pj_str((char*)"plain") #define METHOD_NAME pj_str((char*)"MESSAGE") #define MAXIMUM_MESSAGE_LENGTH 1560 /* PJSIP's sip message limit */ -#define DELIMITER_CHAR "\n\n" +#define DELIMITER_CHAR "\n\n" #define MODE_APPEND std::ios::out || std::ios::app #define MODE_TEST std::ios::out -namespace sfl { - - class InstantMessaging - { - public: - /* - * Class constructor - */ - InstantMessaging(); - - /* - * Class destructor - */ - ~InstantMessaging(); - - /** - * Set maximum size fo this module. - */ - void setMessageMaximumSize(unsigned int max) { messageMaxSize = max; } - - /** - * Return the maximum number if character for a single SIP MESSAGE. - * Longer messages should be splitted in several smaller messages using split_message - */ - unsigned int getMessageMaximumSize(void) { return messageMaxSize; } - - /* - * Register and initialize instant messaging support - */ - bool init (); - - /* - * Open an existing file if possible or create a new one. * - * @param id The current call - * @return int The number of currently open file stream - */ - int openArchive (CallID& id); - - /* - * Close the file corresponding to the specified call - * - * @param id The current call - * @return int The number of remaining open file stream - */ - int closeArchive (CallID& id); - - /* - * Write the text message to the right file - * The call ID is associated to a file descriptor, so it is easy then to retrieve the right file - * - * @param message The text message - * @param id The current call - * @return True if the message could have been successfully saved, False otherwise - */ - bool saveMessage (const std::string& message, const std::string& author, CallID& id, int mode = MODE_APPEND); - - /* - * Receive a string SIP message, for a specific call - * - * @param message The message contained in the TEXT message - * @param id The call recipient of the message - */ - std::string receive (const std::string& message, const std::string& author, CallID& id); - - /* - * Send a SIP string message inside a call - * - * @param id The call ID we will retrieve the invite session from - * @param message The string message, as sent by the client - * - * @return pj_status_t 0 on success - * 1 otherwise - */ - pj_status_t send (pjsip_inv_session*, CallID& id, const std::string&); - - pj_status_t send_message (pjsip_inv_session*, CallID& id, const std::string&); - - std::vector<std::string> split_message (const std::string&); - - - /** - * Notify the clients, through D-Bus, that a new message has arrived - * - * @param id The callID to notify (TODO: accountID?) - */ - pj_status_t notify (CallID& id); - - - /* - * Add a pair file stream / call ID to the private std::map - */ - inline int addFileStream (std::string key, std::ofstream &value) { - return (int)imFiles.size (); - } - - /* - * Remove a pair file stream / call ID from the private std::map - */ - inline int removeFileStream (std::string key) { imFiles.erase (key); return (int)imFiles.size (); } - - private: - - /** - * A queue to handle messages - */ - // std::queue<std::string> queuedMessages; - - /** - * A map to handle opened file descriptors - * A file descriptor is associated to a call ID - */ - std::map<std::string, std::ofstream*> imFiles; - - InstantMessaging(const InstantMessaging&); //No Copy Constructor - InstantMessaging& operator=(const InstantMessaging&); //No Assignment Operator - - /** - * Store the maximum number of character for a SIP MESSAGE - */ - unsigned int messageMaxSize; - }; +namespace sfl +{ + +class InstantMessaging +{ + public: + /* + * Class constructor + */ + InstantMessaging(); + + /* + * Class destructor + */ + ~InstantMessaging(); + + /* + * Register and initialize instant messaging support + */ + bool init (); + + /** + * Set maximum size fo this module. + */ + void setMessageMaximumSize (unsigned int max) { + messageMaxSize = max; + } + + /** + * Return the maximum number if character for a single SIP MESSAGE. + * Longer messages should be splitted in several smaller messages using split_message + */ + unsigned int getMessageMaximumSize (void) { + return messageMaxSize; + } + + /* + * Open an existing file if possible or create a new one. * + * @param id The current call + * @return int The number of currently open file stream + */ + int openArchive (CallID& id); + + /* + * Close the file corresponding to the specified call + * + * @param id The current call + * @return int The number of remaining open file stream + */ + int closeArchive (CallID& id); + + /* + * Write the text message to the right file + * The call ID is associated to a file descriptor, so it is easy then to retrieve the right file + * + * @param message The text message + * @param id The current call + * @return True if the message could have been successfully saved, False otherwise + */ + bool saveMessage (const std::string& message, const std::string& author, CallID& id, int mode = MODE_APPEND); + + /* + * Receive a string SIP message, for a specific call + * + * @param message The message contained in the TEXT message + * @param id The call recipient of the message + */ + std::string receive (const std::string& message, const std::string& author, CallID& id); + + /* + * Send a SIP string message inside a call + * + * @param id The call ID we will retrieve the invite session from + * @param message The string message, as sent by the client + * + * @return pj_status_t 0 on success + * 1 otherwise + */ + pj_status_t send (pjsip_inv_session*, CallID& id, const std::string&); + + pj_status_t send_message (pjsip_inv_session*, CallID& id, const std::string&); + + std::vector<std::string> split_message (const std::string&); + + + /** + * Notify the clients, through D-Bus, that a new message has arrived + * + * @param id The callID to notify (TODO: accountID?) + */ + pj_status_t notify (CallID& id); + + private: + + /** + * A queue to handle messages + */ + // std::queue<std::string> queuedMessages; + + /** + * A map to handle opened file descriptors + * A file descriptor is associated to a call ID + */ + std::map<std::string, std::ofstream*> imFiles; + + InstantMessaging (const InstantMessaging&); //No Copy Constructor + InstantMessaging& operator= (const InstantMessaging&); //No Assignment Operator + + /** + * Maximum size in char of an instant message + */ + unsigned int messageMaxSize; +}; } #endif // _INSTANT_MESSAGING_H diff --git a/sflphone-common/src/sip/sdp.h b/sflphone-common/src/sip/sdp.h index 07c1ecfce7a51a309ffbf693c39b194e6777f084..19336befd5f881ee6a7466ea48d2490ca01aa377 100644 --- a/sflphone-common/src/sip/sdp.h +++ b/sflphone-common/src/sip/sdp.h @@ -49,52 +49,60 @@ class sdpException: public std::exception { - virtual const char* what() const throw() - { - return "An sdpException Occured"; - } + virtual const char* what() const throw() { + return "An sdpException Occured"; + } }; typedef std::vector<std::string> CryptoOffer; -class Sdp { +class Sdp +{ public: - + /* * Class Constructor. * * @param ip_addr */ - Sdp(pj_pool_t *pool); + Sdp (pj_pool_t *pool); /* Class destructor */ ~Sdp(); /* - * Read accessor. Get the list of the local media capabilities. + * Read accessor. Get the list of the local media capabilities. * * @return std::vector<sdpMedia*> the vector containing the different media */ - std::vector<sdpMedia*> get_local_media_cap( void ) { return _local_media_cap; } + std::vector<sdpMedia*> get_local_media_cap (void) { + return _local_media_cap; + } - /* - * Read accessor. Get the sdp session information - * - * @return pjmedia_sdp_session The structure that describes a SDP session - */ - pjmedia_sdp_session* get_local_sdp_session( void ) { return _local_offer; } + /* + * Read accessor. Get the sdp session information + * + * @return pjmedia_sdp_session The structure that describes a SDP session + */ + pjmedia_sdp_session* get_local_sdp_session (void) { + return _local_offer; + } /* * Write accessor. Set the local IP address that will be used in the sdp session */ - void set_ip_address( std::string ip_addr ) { _ip_addr = ip_addr; } + void set_ip_address (std::string ip_addr) { + _ip_addr = ip_addr; + } /* * Read accessor. Get the local IP address */ - std::string get_ip_address( void ) { return _ip_addr; } - + std::string get_ip_address (void) { + return _ip_addr; + } + /* * Build the local SDP offer */ @@ -107,34 +115,39 @@ class Sdp { * @param media The media to add to SDP * @param med The structure to receive the media section */ - void set_media_descriptor_line( sdpMedia* media, pjmedia_sdp_media** p_med ); + void set_media_descriptor_line (sdpMedia* media, pjmedia_sdp_media** p_med); /* Set the zrtp hash that was previously calculated from the hello message in the zrtp layer. * This hash value is unique at the media level. Therefore, if video support is added, one would * have to set the correct zrtp-hash value in the corresponding media section. * @param hash The hello hash of a rtp session. (Only audio at the moment) */ - inline void set_zrtp_hash(const std::string& hash) { _zrtp_hello_hash = hash; _debug("Zrtp hash set with %s\n", hash.c_str()); } + inline void set_zrtp_hash (const std::string& hash) { + _zrtp_hello_hash = hash; + _debug ("Zrtp hash set with %s\n", hash.c_str()); + } + + /* Set the srtp _master_key + * @param mk The Master Key of a srtp session. + */ + inline void set_srtp_crypto (const std::vector<std::string> lc) { + _srtp_crypto = lc; + } - /* Set the srtp _master_key - * @param mk The Master Key of a srtp session. - */ - inline void set_srtp_crypto(const std::vector<std::string> lc) { _srtp_crypto = lc; } - /* * On building an invite outside a dialog, build the local offer and create the * SDP negociator instance with it. */ int create_initial_offer (CodecOrder selectedCodecs); - /* - * On receiving an invite outside a dialog, build the local offer and create the - * SDP negociator instance with the remote offer. - * - * @param remote The remote offer - */ + /* + * On receiving an invite outside a dialog, build the local offer and create the + * SDP negociator instance with the remote offer. + * + * @param remote The remote offer + */ int receiving_initial_offer (pjmedia_sdp_session* remote, CodecOrder selectedCodecs); - + /* * On receiving a message, check if it contains SDP and negotiate. Should be used for * SDP answer and offer but currently is only used for answer. @@ -143,53 +156,53 @@ class Sdp { * @param inv The the invitation * @param rdata The remote data */ - - pj_status_t check_sdp_answer(pjsip_inv_session *inv, pjsip_rx_data *rdata); - + + pj_status_t check_sdp_answer (pjsip_inv_session *inv, pjsip_rx_data *rdata); + /** * Remove all media in the session media vector. */ - void clean_session_media(void); + void clean_session_media (void); /** * Remove all media in local media capability vector */ - void clean_local_media_capabilities(void); + void clean_local_media_capabilities (void); /* * Return a string description of the media added to the session, * ie the local media capabilities */ - std::string media_to_string( void ); + std::string media_to_string (void); /* * Return the codec of the first media after negociation */ - AudioCodec* get_session_media( void ); + AudioCodec* get_session_media (void); /* * read accessor. Return the negociated offer * * @return pjmedia_sdp_session The negociated offer */ - pjmedia_sdp_session* get_negociated_offer( void ){ + pjmedia_sdp_session* get_negociated_offer (void) { return _negociated_offer; } - /* - * Start the sdp negociation. - * - * @return pj_status_t 0 on success - * 1 otherwise - */ - pj_status_t start_negociation( void ); + /* + * Start the sdp negociation. + * + * @return pj_status_t 0 on success + * 1 otherwise + */ + pj_status_t start_negociation (void); - /* - * Retrieve the negociated sdp offer from the sip payload. - * - * @param sdp the negociated offer - */ - void set_negotiated_sdp ( const pjmedia_sdp_session *sdp ); + /* + * Retrieve the negociated sdp offer from the sip payload. + * + * @param sdp the negociated offer + */ + void set_negotiated_sdp (const pjmedia_sdp_session *sdp); /* * Attribute the specified port to every medias provided @@ -200,39 +213,53 @@ class Sdp { */ void attribute_port_to_all_media (int port); - void set_local_extern_audio_port(int port){ _local_extern_audio_port = port; } + void set_local_extern_audio_port (int port) { + _local_extern_audio_port = port; + } - int get_local_extern_audio_port (void){ return _local_extern_audio_port; } + int get_local_extern_audio_port (void) { + return _local_extern_audio_port; + } void toString (void); - /** + /** * Set remote's IP addr. [not protected] * @param ip The remote IP address */ - void set_remote_ip(const std::string& ip) { _remote_ip_addr = ip; } - - /** + void set_remote_ip (const std::string& ip) { + _remote_ip_addr = ip; + } + + /** * Return IP of destination [mutex protected] * @return const std:string The remote IP address */ - const std::string& get_remote_ip() { return _remote_ip_addr; } + const std::string& get_remote_ip() { + return _remote_ip_addr; + } - /** + /** * Set remote's audio port. [not protected] * @param port The remote audio port */ - void set_remote_audio_port(unsigned int port) { _remote_audio_port = port; } + void set_remote_audio_port (unsigned int port) { + _remote_audio_port = port; + } - /** - * Return audio port at destination [mutex protected] + /** + * Return audio port at destination [mutex protected] * @return unsigned int The remote audio port */ - unsigned int get_remote_audio_port() { return _remote_audio_port; } + unsigned int get_remote_audio_port() { + return _remote_audio_port; + } void set_media_transport_info_from_remote_sdp (const pjmedia_sdp_session *remote_sdp); - std::vector<sdpMedia*> get_session_media_list (void) { return _session_media; } + std::vector<sdpMedia*> get_session_media_list (void) { + return _session_media; + } void get_remote_sdp_crypto_from_offer (const pjmedia_sdp_session* remote_sdp, CryptoOffer& crypto_offer); @@ -251,13 +278,13 @@ class Sdp { /** Remote's IP address */ std::string _remote_ip_addr; - + /** Local SDP */ pjmedia_sdp_session *_local_offer; /* The negociated SDP offer */ // Explanation: each endpoint's offer is negociated, and a new sdp offer results from this - // negociation, with the compatible media from each part + // negociation, with the compatible media from each part pjmedia_sdp_session *_negociated_offer; // The pool to allocate memory @@ -273,9 +300,9 @@ class Sdp { /** "a=crypto" sdes local attributes obtained from AudioSrtpSession */ std::vector<std::string> _srtp_crypto; - - Sdp(const Sdp&); //No Copy Constructor - Sdp& operator=(const Sdp&); //No Assignment Operator + + Sdp (const Sdp&); //No Copy Constructor + Sdp& operator= (const Sdp&); //No Assignment Operator void set_local_media_capabilities (CodecOrder selectedCodecs); @@ -284,70 +311,70 @@ class Sdp { * Gives the originator of the session. * Serves as a globally unique identifier for this version of this session description. */ - void sdp_add_origin( void ); + void sdp_add_origin (void); /* * Mandatory field: Protocol version ("v=") * Add the protocol version in the SDP session description */ - void sdp_add_protocol( void ); + void sdp_add_protocol (void); /* * Optional field: Connection data ("c=") * Contains connection data. */ - void sdp_add_connection_info( void ); - + void sdp_add_connection_info (void); + /* * Mandatory field: Session name ("s=") * Add a textual session name. */ - void sdp_add_session_name( void ); + void sdp_add_session_name (void); /* * Optional field: Session information ("s=") * Provides textual information about the session. */ - void sdp_add_session_info( void ){} + void sdp_add_session_info (void) {} /* * Optional field: Uri ("u=") * Add a pointer to additional information about the session. */ - void sdp_add_uri( void ) {} + void sdp_add_uri (void) {} /* * Optional fields: Email address and phone number ("e=" and "p=") * Add contact information for the person responsible for the conference. */ - void sdp_add_email( void ) {} + void sdp_add_email (void) {} /* * Optional field: Bandwidth ("b=") * Denotes the proposed bandwidth to be used by the session or the media . */ - void sdp_add_bandwidth( void ) {} + void sdp_add_bandwidth (void) {} /* * Mandatory field: Timing ("t=") * Specify the start and the stop time for a session. */ - void sdp_add_timing( void ); + void sdp_add_timing (void); /* * Optional field: Time zones ("z=") */ - void sdp_add_time_zone( void ) {} + void sdp_add_time_zone (void) {} /* * Optional field: Encryption keys ("k=") */ - void sdp_add_encryption_key( void ) {} + void sdp_add_encryption_key (void) {} /* * Optional field: Attributes ("a=") */ - void sdp_add_attributes( ); + void sdp_add_attributes(); /* * Mandatory field: Media descriptions ("m=") @@ -357,30 +384,30 @@ class Sdp { std::string convert_int_to_string (int value); void set_remote_ip_from_sdp (const pjmedia_sdp_session *r_sdp); - + void set_remote_audio_port_from_sdp (pjmedia_sdp_media *r_media); void get_remote_sdp_media_from_offer (const pjmedia_sdp_session* r_sdp, pjmedia_sdp_media** r_media); - + /* * Adds a sdes attribute to the given media section. * - * @param media The media to add the srtp attribute to + * @param media The media to add the srtp attribute to */ - void sdp_add_sdes_attribute(std::vector<std::string>& crypto); + void sdp_add_sdes_attribute (std::vector<std::string>& crypto); - /* - * Adds a zrtp-hash attribute to + /* + * Adds a zrtp-hash attribute to * the given media section. The hello hash is * available only after is has been computed - * in the AudioZrtpSession constructor. + * in the AudioZrtpSession constructor. * - * @param media The media to add the zrtp-hash attribute to + * @param media The media to add the zrtp-hash attribute to * @param hash The hash to which the attribute should be set to - */ - void sdp_add_zrtp_attribute(pjmedia_sdp_media* media, std::string hash); - + */ + void sdp_add_zrtp_attribute (pjmedia_sdp_media* media, std::string hash); + }; diff --git a/sflphone-common/src/sip/sdpmedia.h b/sflphone-common/src/sip/sdpmedia.h index 96d47e326b424ebb1c75c9298342aec9559b8187..54a9a27d1d2b3d4cb459d670a938c5cbae36551a 100644 --- a/sflphone-common/src/sip/sdpmedia.h +++ b/sflphone-common/src/sip/sdpmedia.h @@ -83,19 +83,23 @@ typedef enum mediaType mediaType; class sdpMedia { public: - sdpMedia( int type ); - sdpMedia( std::string type, int port, std::string dir = DEFAULT_STREAM_DIRECTION); + sdpMedia (int type); + sdpMedia (std::string type, int port, std::string dir = DEFAULT_STREAM_DIRECTION); ~sdpMedia(); /* * Read accessor. Return the list of codecs */ - std::vector<AudioCodec*> get_media_codec_list() { return _codec_list; } + std::vector<AudioCodec*> get_media_codec_list() { + return _codec_list; + } /* * Read accessor. Return the type of media */ - mediaType get_media_type() { return _media_type; } + mediaType get_media_type() { + return _media_type; + } /* * Read accessor. Return the type of media @@ -105,59 +109,69 @@ class sdpMedia /* * Set the media type */ - void set_media_type( int type ) { _media_type = (mediaType)type; } + void set_media_type (int type) { + _media_type = (mediaType) type; + } /* * Read accessor. Return the transport port */ - int get_port() { return _port; } + int get_port() { + return _port; + } /* * Write accessor. Set the transport port */ - void set_port( int port ) { _port = port; } + void set_port (int port) { + _port = port; + } /* * Add a codec in the current media codecs vector * * @param payload The payload type */ - void add_codec( AudioCodec *codec ); + void add_codec (AudioCodec *codec); /* * Remove a codec from the current media codecs vector * * @param codec_name The codec encoding name */ - void remove_codec( std::string codec_name ); + void remove_codec (std::string codec_name); /* * Remove all the codecs from the list */ - void clear_codec_list( void ); + void clear_codec_list (void); /* * Return a string description of the current media - */ - std::string to_string( void ); + */ + std::string to_string (void); /* * Set the stream direction of the current media * ie: sendrecv, sendonly,... */ - void set_stream_direction( int direction ) { _stream_type = (streamDirection)direction; } + void set_stream_direction (int direction) { + _stream_type = (streamDirection) direction; + } /* * Get the stream direction of the current media * ie: sendrecv, sendonly,... */ - streamDirection get_stream_direction( void ) { return _stream_type; } + streamDirection get_stream_direction (void) { + return _stream_type; + } /* * Get the stream direction string description of the current media * ie: sendrecv, sendonly,... */ - std::string get_stream_direction_str( void ); + std::string get_stream_direction_str (void); private: /* The type of media */ diff --git a/sflphone-common/src/sip/sipaccount.cpp b/sflphone-common/src/sip/sipaccount.cpp index 2d6aa14f053c46546706c6023778c8c89ad1e4e1..0a31e1f98a9367a12afe5828582bfc945eef1954 100644 --- a/sflphone-common/src/sip/sipaccount.cpp +++ b/sflphone-common/src/sip/sipaccount.cpp @@ -34,30 +34,102 @@ #include "manager.h" #include "user_cfg.h" #include <pwd.h> +#include <sstream> + +Credentials::Credentials() : credentialCount (0) {} + +Credentials::~Credentials() {} + +void Credentials::setNewCredential (std::string username, std::string password, std::string realm) +{ + credentialArray[credentialCount].username = username; + credentialArray[credentialCount].password = password; + credentialArray[credentialCount].realm = realm; + +} + +CredentialItem *Credentials::getCredential (int index) +{ + if ( (index >= 0) && (index < credentialCount)) + return & (credentialArray[index]); + else + return NULL; +} + +void Credentials::serialize (Conf::YamlEmitter *emitter UNUSED) +{ + +} + +void Credentials::unserialize (Conf::MappingNode *map) +{ + + Conf::ScalarNode *val = NULL; + + _debug ("SipAccount: Unserialize"); + + val = (Conf::ScalarNode *) (map->getValue (credentialCountKey)); + + if (val) { + credentialCount = atoi (val->getValue().data()); + val = NULL; + } +} + + SIPAccount::SIPAccount (const AccountID& accountID) - : Account (accountID, "sip") + : Account (accountID, "SIP") , _routeSet ("") , _regc (NULL) , _bRegister (false) , _registrationExpire ("") + , _interface ("default") , _publishedSameasLocal (true) , _publishedIpAddress ("") , _localPort (atoi (DEFAULT_SIP_PORT)) , _publishedPort (atoi (DEFAULT_SIP_PORT)) + , _serviceRoute ("") , _tlsListenerPort (atoi (DEFAULT_SIP_TLS_PORT)) , _transportType (PJSIP_TRANSPORT_UNSPECIFIED) , _transport (NULL) , _resolveOnce (false) - , _credentialCount (0) , _cred (NULL) , _realm (DEFAULT_REALM) , _authenticationUsername ("") , _tlsSetting (NULL) , _dtmfType (OVERRTP) - , _displayName ("") + , _tlsEnable ("false") + , _tlsPortStr (DEFAULT_SIP_TLS_PORT) + , _tlsCaListFile ("") + , _tlsCertificateFile ("") + , _tlsPrivateKeyFile ("") + , _tlsPassword ("") + , _tlsMethod ("TLSv1") + , _tlsCiphers ("") + , _tlsServerName ("") + , _tlsVerifyServer (true) + , _tlsVerifyClient (true) + , _tlsRequireClientCertificate (true) + , _tlsNegotiationTimeoutSec ("2") + , _tlsNegotiationTimeoutMsec ("0") + , _stunServer (DFT_STUN_SERVER) + , _stunEnabled (false) + , _srtpEnabled (false) + , _srtpKeyExchange ("sdes") + , _srtpFallback (false) + , _zrtpDisplaySas (true) + , _zrtpDisplaySasOnce (false) + , _zrtpHelloHash (true) + , _zrtpNotSuppWarning (true) { + _debug ("Sip account constructor called"); + + _stunServerName.ptr = NULL; + _stunServerName.slen = 0; + _stunPort = 0; + // IP2IP settings must be loaded before singleton instanciation, cannot call it here... // _link = SIPVoIPLink::instance (""); @@ -70,7 +142,8 @@ SIPAccount::SIPAccount (const AccountID& accountID) SIPAccount::~SIPAccount() { /* One SIP account less connected to the sip voiplink */ - dynamic_cast<SIPVoIPLink*> (_link)->decrementClients(); + if (_accountID != "default") + dynamic_cast<SIPVoIPLink*> (_link)->decrementClients(); /* Delete accounts-related information */ _regc = NULL; @@ -78,6 +151,769 @@ SIPAccount::~SIPAccount() free (_tlsSetting); } +void SIPAccount::serialize (Conf::YamlEmitter *emitter) +{ + + _debug ("SipAccount: serialize %s", _accountID.c_str()); + + + Conf::MappingNode accountmap (NULL); + Conf::MappingNode credentialmap (NULL); + Conf::MappingNode srtpmap (NULL); + Conf::MappingNode zrtpmap (NULL); + Conf::MappingNode tlsmap (NULL); + + Conf::ScalarNode id (Account::_accountID); + Conf::ScalarNode username (Account::_username); + Conf::ScalarNode password (Account::_password); + Conf::ScalarNode alias (Account::_alias); + Conf::ScalarNode hostname (Account::_hostname); + Conf::ScalarNode enable (_enabled ? "true" : "false"); + Conf::ScalarNode type (Account::_type); + Conf::ScalarNode expire (_registrationExpire); + Conf::ScalarNode interface (_interface); + std::stringstream portstr; + portstr << _localPort; + Conf::ScalarNode port (portstr.str()); + Conf::ScalarNode serviceRoute (_serviceRoute); + + Conf::ScalarNode mailbox ("97"); + Conf::ScalarNode publishAddr (_publishedIpAddress); + std::stringstream publicportstr; + publicportstr << _publishedPort; + Conf::ScalarNode publishPort (publicportstr.str()); + Conf::ScalarNode sameasLocal (_publishedSameasLocal ? "true" : "false"); + Conf::ScalarNode resolveOnce (_resolveOnce ? "true" : "false"); + Conf::ScalarNode codecs (_codecStr); + Conf::ScalarNode ringtonePath (_ringtonePath); + Conf::ScalarNode ringtoneEnabled (_ringtoneEnabled ? "true" : "false"); + Conf::ScalarNode stunServer (_stunServer); + Conf::ScalarNode stunEnabled (_stunEnabled ? "true" : "false"); + Conf::ScalarNode displayName (_displayName); + Conf::ScalarNode dtmfType (_dtmfType==0 ? "overrtp" : "sipinfo"); + + std::stringstream countstr; + countstr << 0; + Conf::ScalarNode count (countstr.str()); + + Conf::ScalarNode srtpenabled (_srtpEnabled ? "true" : "false"); + Conf::ScalarNode keyExchange (_srtpKeyExchange); + Conf::ScalarNode rtpFallback (_srtpFallback ? "true" : "false"); + + Conf::ScalarNode displaySas (_zrtpDisplaySas ? "true" : "false"); + Conf::ScalarNode displaySasOnce (_zrtpDisplaySasOnce ? "true" : "false"); + Conf::ScalarNode helloHashEnabled (_zrtpHelloHash ? "true" : "false"); + Conf::ScalarNode notSuppWarning (_zrtpNotSuppWarning ? "true" : "false"); + + Conf::ScalarNode tlsport (_tlsPortStr); + Conf::ScalarNode certificate (_tlsCertificateFile); + Conf::ScalarNode calist (_tlsCaListFile); + Conf::ScalarNode ciphers (_tlsCiphers); + Conf::ScalarNode tlsenabled (_tlsEnable); + Conf::ScalarNode tlsmethod (_tlsMethod); + Conf::ScalarNode timeout (_tlsNegotiationTimeoutSec); + Conf::ScalarNode tlspassword (_tlsPassword); + Conf::ScalarNode privatekey (_tlsPrivateKeyFile); + Conf::ScalarNode requirecertif (_tlsRequireClientCertificate ? "true" : "false"); + Conf::ScalarNode server (_tlsServerName); + Conf::ScalarNode verifyclient (_tlsVerifyServer ? "true" : "false"); + Conf::ScalarNode verifyserver (_tlsVerifyClient ? "true" : "false"); + + accountmap.setKeyValue (aliasKey, &alias); + accountmap.setKeyValue (typeKey, &type); + accountmap.setKeyValue (idKey, &id); + accountmap.setKeyValue (usernameKey, &username); + accountmap.setKeyValue (passwordKey, &password); + accountmap.setKeyValue (hostnameKey, &hostname); + accountmap.setKeyValue (accountEnableKey, &enable); + accountmap.setKeyValue (mailboxKey, &mailbox); + accountmap.setKeyValue (expireKey, &expire); + accountmap.setKeyValue (interfaceKey, &interface); + accountmap.setKeyValue (portKey, &port); + accountmap.setKeyValue (stunServerKey, &stunServer); + accountmap.setKeyValue (stunEnabledKey, &stunEnabled); + accountmap.setKeyValue (publishAddrKey, &publishAddr); + accountmap.setKeyValue (publishPortKey, &publishPort); + accountmap.setKeyValue (sameasLocalKey, &sameasLocal); + accountmap.setKeyValue (resolveOnceKey, &resolveOnce); + accountmap.setKeyValue (serviceRouteKey, &serviceRoute); + accountmap.setKeyValue (dtmfTypeKey, &dtmfType); + accountmap.setKeyValue (displayNameKey, &displayName); + accountmap.setKeyValue (codecsKey, &codecs); + accountmap.setKeyValue (ringtonePathKey, &ringtonePath); + accountmap.setKeyValue (ringtoneEnabledKey, &ringtoneEnabled); + + accountmap.setKeyValue (srtpKey, &srtpmap); + srtpmap.setKeyValue (srtpEnableKey, &srtpenabled); + srtpmap.setKeyValue (keyExchangeKey, &keyExchange); + srtpmap.setKeyValue (rtpFallbackKey, &rtpFallback); + + accountmap.setKeyValue (zrtpKey, &zrtpmap); + zrtpmap.setKeyValue (displaySasKey, &displaySas); + zrtpmap.setKeyValue (displaySasOnceKey, &displaySasOnce); + zrtpmap.setKeyValue (helloHashEnabledKey, &helloHashEnabled); + zrtpmap.setKeyValue (notSuppWarningKey, ¬SuppWarning); + + accountmap.setKeyValue (credKey, &credentialmap); + credentialmap.setKeyValue (credentialCountKey, &count); + + accountmap.setKeyValue (tlsKey, &tlsmap); + tlsmap.setKeyValue (tlsPortKey, &tlsport); + tlsmap.setKeyValue (certificateKey, &certificate); + tlsmap.setKeyValue (calistKey, &calist); + tlsmap.setKeyValue (ciphersKey, &ciphers); + tlsmap.setKeyValue (tlsEnableKey, &tlsenabled); + tlsmap.setKeyValue (methodKey, &tlsmethod); + tlsmap.setKeyValue (timeoutKey, &timeout); + tlsmap.setKeyValue (tlsPasswordKey, &tlspassword); + tlsmap.setKeyValue (privateKeyKey, &privatekey); + tlsmap.setKeyValue (requireCertifKey, &requirecertif); + tlsmap.setKeyValue (serverKey, &server); + tlsmap.setKeyValue (verifyClientKey, &verifyclient); + tlsmap.setKeyValue (verifyServerKey, &verifyserver); + + try { + emitter->serializeAccount (&accountmap); + } catch (Conf::YamlEmitterException &e) { + _error ("ConfigTree: %s", e.what()); + } +} + + +void SIPAccount::unserialize (Conf::MappingNode *map) +{ + Conf::ScalarNode *val; + Conf::MappingNode *srtpMap; + Conf::MappingNode *tlsMap; + Conf::MappingNode *zrtpMap; + Conf::MappingNode *credMap; + + _debug ("SipAccount: Unserialize %s", _accountID.c_str()); + + val = (Conf::ScalarNode *) (map->getValue (aliasKey)); + + if (val) { + _alias = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (typeKey)); + + if (val) { + _type = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (idKey)); + + if (val) { + _accountID = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (usernameKey)); + + if (val) { + _username = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (passwordKey)); + + if (val) { + _password = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (hostnameKey)); + + if (val) { + _hostname = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (accountEnableKey)); + + if (val) { + _enabled = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + // val = (Conf::ScalarNode *)(map->getValue(mailboxKey)); + + val = (Conf::ScalarNode *) (map->getValue (codecsKey)); + + if (val) { + _codecStr = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (ringtonePathKey)); + + if (val) { + _ringtonePath = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (ringtoneEnabledKey)); + + if (val) { + _ringtoneEnabled = (val->getValue() == "true") ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (expireKey)); + + if (val) { + _registrationExpire = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (interfaceKey)); + + if (val) { + _interface = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (portKey)); + + if (val) { + _localPort = atoi (val->getValue().data()); + val = NULL; + } + + // val = (Conf::ScalarNode *)(map->getValue(mailboxKey)); + val = (Conf::ScalarNode *) (map->getValue (publishAddrKey)); + + if (val) { + _publishedIpAddress = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (publishPortKey)); + + if (val) { + _publishedPort = atoi (val->getValue().data()); + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (sameasLocalKey)); + + if (val) { + _publishedSameasLocal = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (resolveOnceKey)); + + if (val) { + _resolveOnce = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (dtmfTypeKey)); + + if (val) { + val = NULL; + } + + // _dtmfType = atoi(val->getValue(); + val = (Conf::ScalarNode *) (map->getValue (serviceRouteKey)); + + if (val) { + _serviceRoute = val->getValue(); + } + + // stun enabled + val = (Conf::ScalarNode *) (map->getValue (stunEnabledKey)); + + if (val) { + _stunEnabled = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (map->getValue (stunServerKey)); + + if (val) { + _stunServer = val->getValue(); + val = NULL; + } + + _stunServerName = pj_str ( (char*) _stunServer.data()); + + credMap = (Conf::MappingNode *) (map->getValue (credKey)); + credentials.unserialize (credMap); + + val = (Conf::ScalarNode *) (map->getValue (displayNameKey)); + + if (val) { + _displayName = val->getValue(); + val = NULL; + } + + // get srtp submap + srtpMap = (Conf::MappingNode *) (map->getValue (srtpKey)); + + if (!srtpMap) + throw SipAccountException (" did not found srtp map"); + + val = (Conf::ScalarNode *) (srtpMap->getValue (srtpEnableKey)); + + if (val) { + _srtpEnabled = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (srtpMap->getValue (keyExchangeKey)); + + if (val) { + _srtpKeyExchange = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (srtpMap->getValue (rtpFallbackKey)); + + if (val) { + _srtpFallback = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + // get zrtp submap + zrtpMap = (Conf::MappingNode *) (map->getValue (zrtpKey)); + + if (!zrtpMap) + throw SipAccountException (" did not found zrtp map"); + + val = (Conf::ScalarNode *) (zrtpMap->getValue (displaySasKey)); + + if (val) { + _zrtpDisplaySas = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (zrtpMap->getValue (displaySasOnceKey)); + + if (val) { + _zrtpDisplaySasOnce = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (zrtpMap->getValue (helloHashEnabledKey)); + + if (val) { + _zrtpHelloHash = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (zrtpMap->getValue (notSuppWarningKey)); + + if (val) { + _zrtpNotSuppWarning = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + // get tls submap + tlsMap = (Conf::MappingNode *) (map->getValue (tlsKey)); + + if (!tlsMap) + throw SipAccountException (" did not found tls map"); + + val = (Conf::ScalarNode *) (tlsMap->getValue (tlsEnableKey)); + + if (val) { + _tlsEnable = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (tlsMap->getValue (tlsPortKey)); + + if (val) { + _tlsPortStr = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (tlsMap->getValue (certificateKey)); + + if (val) { + _tlsCertificateFile = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (tlsMap->getValue (calistKey)); + + if (val) { + _tlsCaListFile = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (tlsMap->getValue (ciphersKey)); + + if (val) { + _tlsCiphers = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (tlsMap->getValue (methodKey)); + + if (val) { + _tlsMethod = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (tlsMap->getValue (timeoutKey)); + + if (val) _tlsNegotiationTimeoutSec = val->getValue(); + + if (val) { + _tlsNegotiationTimeoutMsec = val->getValue(); + val=NULL; + } + + val = (Conf::ScalarNode *) (tlsMap->getValue (tlsPasswordKey)); + + if (val) { + _tlsPassword = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (tlsMap->getValue (privateKeyKey)); + + if (val) { + _tlsPrivateKeyFile = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (tlsMap->getValue (requireCertifKey)); + + if (val) { + _tlsRequireClientCertificate = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (tlsMap->getValue (serverKey)); + + if (val) { + _tlsServerName = val->getValue(); + val = NULL; + } + + val = (Conf::ScalarNode *) (tlsMap->getValue (verifyClientKey)); + + if (val) { + _tlsVerifyServer = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + + val = (Conf::ScalarNode *) (tlsMap->getValue (verifyServerKey)); + + if (val) { + _tlsVerifyClient = (val->getValue().compare ("true") == 0) ? true : false; + val = NULL; + } + +} + + +void SIPAccount::setAccountDetails (const std::map<std::string, std::string>& details) +{ + + std::map<std::string, std::string> map_cpy; + std::map<std::string, std::string>::iterator iter; + + _debug ("SipAccount: set account details %s", _accountID.c_str()); + + // Work on a copy + map_cpy = details; + + std::string alias; + std::string type; + std::string hostname; + std::string username; + std::string password; + std::string mailbox; + std::string accountEnable; + std::string ringtonePath; + std::string ringtoneEnabled; + + // Account setting common to SIP and IAX + find_in_map (CONFIG_ACCOUNT_ALIAS, alias) + find_in_map (CONFIG_ACCOUNT_TYPE, type) + find_in_map (HOSTNAME, hostname) + find_in_map (USERNAME, username) + find_in_map (PASSWORD, password) + find_in_map (CONFIG_ACCOUNT_MAILBOX, mailbox); + find_in_map (CONFIG_ACCOUNT_ENABLE, accountEnable); + find_in_map (CONFIG_RINGTONE_PATH, ringtonePath); + find_in_map (CONFIG_RINGTONE_ENABLED, ringtoneEnabled); + + setAlias (alias); + setType (type); + setUsername (username); + setHostname (hostname); + setPassword (password); + setEnabled ( (accountEnable == "true")); + setRingtonePath (ringtonePath); + setRingtoneEnabled ( (ringtoneEnabled == "true")); + + // SIP specific account settings + if (getType() == "SIP") { + + std::string ua_name; + std::string realm; + std::string routeset; + std::string authenticationName; + + std::string resolveOnce; + std::string registrationExpire; + + std::string displayName; + std::string localInterface; + std::string publishedSameasLocal; + std::string localAddress; + std::string publishedAddress; + std::string localPort; + std::string publishedPort; + std::string stunEnable; + std::string stunServer; + std::string dtmfType; + std::string srtpEnable; + std::string srtpRtpFallback; + std::string zrtpDisplaySas; + std::string zrtpDisplaySasOnce; + std::string zrtpNotSuppWarning; + std::string zrtpHelloHash; + std::string srtpKeyExchange; + + std::string tlsListenerPort; + std::string tlsEnable; + std::string tlsCaListFile; + std::string tlsCertificateFile; + std::string tlsPrivateKeyFile; + std::string tlsPassword; + std::string tlsMethod; + std::string tlsCiphers; + std::string tlsServerName; + std::string tlsVerifyServer; + std::string tlsVerifyClient; + std::string tlsRequireClientCertificate; + std::string tlsNegotiationTimeoutSec; + std::string tlsNegotiationTimeoutMsec; + + // general sip settings + find_in_map (DISPLAY_NAME, displayName) + find_in_map (ROUTESET, routeset) + find_in_map (LOCAL_INTERFACE, localInterface) + find_in_map (PUBLISHED_SAMEAS_LOCAL, publishedSameasLocal) + find_in_map (PUBLISHED_ADDRESS, publishedAddress) + find_in_map (LOCAL_PORT, localPort) + find_in_map (PUBLISHED_PORT, publishedPort) + find_in_map (STUN_ENABLE, stunEnable) + find_in_map (STUN_SERVER, stunServer) + find_in_map (ACCOUNT_DTMF_TYPE, dtmfType) + find_in_map (CONFIG_ACCOUNT_RESOLVE_ONCE, resolveOnce) + find_in_map (CONFIG_ACCOUNT_REGISTRATION_EXPIRE, registrationExpire) + + setDisplayName (displayName); + setServiceRoute (routeset); + setLocalInterface (localInterface); + setPublishedSameasLocal ( (publishedSameasLocal.compare ("true") == 0) ? true : false); + setPublishedAddress (publishedAddress); + setLocalPort (atoi (localPort.data())); + setPublishedPort (atoi (publishedPort.data())); + setStunServer (stunServer); + setStunEnabled ( (stunEnable == "true")); + setResolveOnce ( (resolveOnce.compare ("true") ==0) ? true : false); + setRegistrationExpire (registrationExpire); + + // sip credential + find_in_map (REALM, realm) + find_in_map (AUTHENTICATION_USERNAME, authenticationName) + find_in_map (USERAGENT, ua_name) + + setUseragent (ua_name); + + // srtp settings + find_in_map (SRTP_ENABLE, srtpEnable) + find_in_map (SRTP_RTP_FALLBACK, srtpRtpFallback) + find_in_map (ZRTP_DISPLAY_SAS, zrtpDisplaySas) + find_in_map (ZRTP_DISPLAY_SAS_ONCE, zrtpDisplaySasOnce) + find_in_map (ZRTP_NOT_SUPP_WARNING, zrtpNotSuppWarning) + find_in_map (ZRTP_HELLO_HASH, zrtpHelloHash) + find_in_map (SRTP_KEY_EXCHANGE, srtpKeyExchange) + + setSrtpEnable ( (srtpEnable.compare ("true") == 0) ? true : false); + setSrtpFallback ( (srtpRtpFallback.compare ("true") == 0) ? true : false); + setZrtpDisplaySas ( (zrtpDisplaySas.compare ("true") == 0) ? true : false); + setZrtpDiaplaySasOnce ( (zrtpDisplaySasOnce.compare ("true") == 0) ? true : false); + setZrtpNotSuppWarning ( (zrtpNotSuppWarning.compare ("true") == 0) ? true : false); + setZrtpHelloHash ( (zrtpHelloHash.compare ("true") == 0) ? true : false); + // sipaccount->setSrtpKeyExchange((srtpKeyExchange.compare("true") == 0) ? true : false); + setSrtpKeyExchange (srtpKeyExchange); + + // TLS settings + // The TLS listener is unique and globally defined through IP2IP_PROFILE + if (_accountID == IP2IP_PROFILE) { + find_in_map (TLS_LISTENER_PORT, tlsListenerPort) + } + + find_in_map (TLS_ENABLE, tlsEnable) + find_in_map (TLS_CA_LIST_FILE, tlsCaListFile) + find_in_map (TLS_CERTIFICATE_FILE, tlsCertificateFile) + find_in_map (TLS_PRIVATE_KEY_FILE, tlsPrivateKeyFile) + find_in_map (TLS_PASSWORD, tlsPassword) + find_in_map (TLS_METHOD, tlsMethod) + find_in_map (TLS_CIPHERS, tlsCiphers) + find_in_map (TLS_SERVER_NAME, tlsServerName) + find_in_map (TLS_VERIFY_SERVER, tlsVerifyServer) + find_in_map (TLS_VERIFY_CLIENT, tlsVerifyClient) + find_in_map (TLS_REQUIRE_CLIENT_CERTIFICATE, tlsRequireClientCertificate) + find_in_map (TLS_NEGOTIATION_TIMEOUT_SEC, tlsNegotiationTimeoutSec) + find_in_map (TLS_NEGOTIATION_TIMEOUT_MSEC, tlsNegotiationTimeoutMsec) + + if (_accountID == IP2IP_PROFILE) { + setTlsListenerPort (atoi (tlsListenerPort.data())); + } + + setTlsEnable (tlsEnable); + setTlsCaListFile (tlsCaListFile); + setTlsCertificateFile (tlsCertificateFile); + setTlsPrivateKeyFile (tlsPrivateKeyFile); + setTlsPassword (tlsPassword); + setTlsMethod (tlsMethod); + setTlsCiphers (tlsCiphers); + setTlsServerName (tlsServerName); + setTlsVerifyServer (tlsVerifyServer.compare ("true") ? true : false); + setTlsVerifyClient (tlsVerifyServer.compare ("true") ? true : false); + setTlsRequireClientCertificate (tlsRequireClientCertificate.compare ("true") ? true : false); + setTlsNegotiationTimeoutSec (tlsNegotiationTimeoutSec); + setTlsNegotiationTimeoutMsec (tlsNegotiationTimeoutMsec); + + if (!Manager::instance().preferences.getMd5Hash()) { + setPassword (password); + } else { + // Make sure not to re-hash the password field if + // it is already saved as a MD5 Hash. + // TODO: This test is weak. Fix this. + if ( (password.compare (getPassword()) != 0)) { + _debug ("SipAccount: Password sent and password from config are different. Re-hashing"); + std::string hash; + + if (authenticationName.empty()) { + hash = Manager::instance().computeMd5HashFromCredential (username, password, realm); + } else { + hash = Manager::instance().computeMd5HashFromCredential (authenticationName, password, realm); + } + + setPassword (hash); + } + } + } +} + +std::map<std::string, std::string> SIPAccount::getAccountDetails() +{ + _debug ("SipAccount: get account details %s", _accountID.c_str()); + + std::map<std::string, std::string> a; + + a.insert (std::pair<std::string, std::string> (ACCOUNT_ID, _accountID)); + // The IP profile does not allow to set an alias + (_accountID == IP2IP_PROFILE) ? + a.insert (std::pair<std::string, std::string> (CONFIG_ACCOUNT_ALIAS, IP2IP_PROFILE)) : + a.insert (std::pair<std::string, std::string> (CONFIG_ACCOUNT_ALIAS, getAlias())); + + a.insert (std::pair<std::string, std::string> (CONFIG_ACCOUNT_ENABLE, isEnabled() ? "true" : "false")); + a.insert (std::pair<std::string, std::string> (CONFIG_ACCOUNT_TYPE, getType())); + a.insert (std::pair<std::string, std::string> (HOSTNAME, getHostname())); + a.insert (std::pair<std::string, std::string> (USERNAME, getUsername())); + a.insert (std::pair<std::string, std::string> (PASSWORD, getPassword())); + + a.insert (std::pair<std::string, std::string> (CONFIG_RINGTONE_PATH, getRingtonePath())); + a.insert (std::pair<std::string, std::string> (CONFIG_RINGTONE_ENABLED, getRingtoneEnabled() ? "true" : "false")); + + RegistrationState state = Unregistered; + std::string registrationStateCode; + std::string registrationStateDescription; + + + if (_accountID == IP2IP_PROFILE) { + registrationStateCode = EMPTY_FIELD; + registrationStateDescription = "Direct IP call"; + } else { + state = getRegistrationState(); + int code = getRegistrationStateDetailed().first; + std::stringstream out; + out << code; + registrationStateCode = out.str(); + registrationStateDescription = getRegistrationStateDetailed().second; + } + + + (_accountID == IP2IP_PROFILE) ? + a.insert (std::pair<std::string, std::string> (REGISTRATION_STATUS, "READY")) : + a.insert (std::pair<std::string, std::string> (REGISTRATION_STATUS, Manager::instance().mapStateNumberToString (state))); + + a.insert (std::pair<std::string, std::string> (REGISTRATION_STATE_CODE, registrationStateCode)); + a.insert (std::pair<std::string, std::string> (REGISTRATION_STATE_DESCRIPTION, registrationStateDescription)); + + + // Add sip specific details + if (getType() == "SIP") { + + a.insert (std::pair<std::string, std::string> (ROUTESET, getServiceRoute())); + a.insert (std::pair<std::string, std::string> (CONFIG_ACCOUNT_RESOLVE_ONCE, isResolveOnce() ? "true" : "false")); + a.insert (std::pair<std::string, std::string> (REALM, _realm)); + a.insert (std::pair<std::string, std::string> (USERAGENT, getUseragent())); + + a.insert (std::pair<std::string, std::string> (CONFIG_ACCOUNT_REGISTRATION_EXPIRE, getRegistrationExpire())); + a.insert (std::pair<std::string, std::string> (LOCAL_INTERFACE, getLocalInterface())); + a.insert (std::pair<std::string, std::string> (PUBLISHED_SAMEAS_LOCAL, getPublishedSameasLocal() ? "true" : "false")); + a.insert (std::pair<std::string, std::string> (PUBLISHED_ADDRESS, getPublishedAddress())); + + std::stringstream localport; + localport << getLocalPort(); + a.insert (std::pair<std::string, std::string> (LOCAL_PORT, localport.str())); + std::stringstream publishedport; + publishedport << getPublishedPort(); + a.insert (std::pair<std::string, std::string> (PUBLISHED_PORT, publishedport.str())); + a.insert (std::pair<std::string, std::string> (STUN_ENABLE, isStunEnabled() ? "true" : "false")); + a.insert (std::pair<std::string, std::string> (STUN_SERVER, getStunServer())); + a.insert (std::pair<std::string, std::string> (ACCOUNT_DTMF_TYPE, (getDtmfType() == 0) ? "0" : "1")); + + a.insert (std::pair<std::string, std::string> (SRTP_KEY_EXCHANGE, getSrtpKeyExchange())); + a.insert (std::pair<std::string, std::string> (SRTP_ENABLE, getSrtpEnable() ? "true" : "false")); + a.insert (std::pair<std::string, std::string> (SRTP_RTP_FALLBACK, getSrtpFallback() ? "true" : "false")); + + a.insert (std::pair<std::string, std::string> (ZRTP_DISPLAY_SAS, getZrtpDisplaySas() ? "true" : "false")); + a.insert (std::pair<std::string, std::string> (ZRTP_DISPLAY_SAS_ONCE, getZrtpDiaplaySasOnce() ? "true" : "false")); + a.insert (std::pair<std::string, std::string> (ZRTP_HELLO_HASH, getZrtpHelloHash() ? "true" : "false")); + a.insert (std::pair<std::string, std::string> (ZRTP_NOT_SUPP_WARNING, getZrtpNotSuppWarning() ? "true" : "false")); + + // TLS listener is unique and parameters are modified through IP2IP_PROFILE + std::stringstream tlslistenerport; + tlslistenerport << getTlsListenerPort(); + a.insert (std::pair<std::string, std::string> (TLS_LISTENER_PORT, tlslistenerport.str())); + a.insert (std::pair<std::string, std::string> (TLS_ENABLE, getTlsEnable())); + a.insert (std::pair<std::string, std::string> (TLS_CA_LIST_FILE, getTlsCaListFile())); + a.insert (std::pair<std::string, std::string> (TLS_CERTIFICATE_FILE, getTlsCertificateFile())); + a.insert (std::pair<std::string, std::string> (TLS_PRIVATE_KEY_FILE, getTlsPrivateKeyFile())); + a.insert (std::pair<std::string, std::string> (TLS_PASSWORD, getTlsPassword())); + a.insert (std::pair<std::string, std::string> (TLS_METHOD, getTlsMethod())); + a.insert (std::pair<std::string, std::string> (TLS_CIPHERS, getTlsCiphers())); + a.insert (std::pair<std::string, std::string> (TLS_SERVER_NAME, getTlsServerName())); + a.insert (std::pair<std::string, std::string> (TLS_VERIFY_SERVER, getTlsVerifyServer() ? "true" : "false")); + a.insert (std::pair<std::string, std::string> (TLS_VERIFY_CLIENT, getTlsVerifyClient() ? "true" : "false")); + a.insert (std::pair<std::string, std::string> (TLS_REQUIRE_CLIENT_CERTIFICATE, getTlsRequireClientCertificate() ? "true" : "false")); + a.insert (std::pair<std::string, std::string> (TLS_NEGOTIATION_TIMEOUT_SEC, getTlsNegotiationTimeoutSec())); + a.insert (std::pair<std::string, std::string> (TLS_NEGOTIATION_TIMEOUT_MSEC, getTlsNegotiationTimeoutMsec())); + + } + + return a; + +} + // void SIPAccount::setVoIPLink(VoIPLink *link) { void SIPAccount::setVoIPLink() @@ -91,31 +927,28 @@ void SIPAccount::setVoIPLink() int SIPAccount::initCredential (void) { - int credentialCount = 0; - credentialCount = Manager::instance().getConfigInt (_accountID, CONFIG_CREDENTIAL_NUMBER); - credentialCount += 1; + _debug ("SipAccount: Init credential"); bool md5HashingEnabled = false; int dataType = 0; - md5HashingEnabled = Manager::instance().getConfigBool (PREFERENCES, CONFIG_MD5HASH); + md5HashingEnabled = Manager::instance().preferences.getMd5Hash(); std::string digest; // Create the credential array - pjsip_cred_info * cred_info = (pjsip_cred_info *) malloc (sizeof (pjsip_cred_info) * (credentialCount)); + pjsip_cred_info * cred_info = (pjsip_cred_info *) malloc (sizeof (pjsip_cred_info) * (getCredentialCount())); if (cred_info == NULL) { _error ("SipAccount: Error: Failed to set cred_info for account %s", _accountID.c_str()); return !SUCCESS; } - pj_bzero (cred_info, sizeof (pjsip_cred_info) *credentialCount); + pj_bzero (cred_info, sizeof (pjsip_cred_info) * getCredentialCount()); // Use authentication username if provided - if (!_authenticationUsername.empty()) { + if (!_authenticationUsername.empty()) cred_info[0].username = pj_str (strdup (_authenticationUsername.c_str())); - } else { + else cred_info[0].username = pj_str (strdup (_username.c_str())); - } // Set password cred_info[0].data = pj_str (strdup (_password.c_str())); @@ -141,17 +974,12 @@ int SIPAccount::initCredential (void) int i; - for (i = 1; i < credentialCount; i++) { - std::string credentialIndex; - std::stringstream streamOut; - streamOut << i - 1; - credentialIndex = streamOut.str(); - - std::string section = std::string ("Credential") + std::string (":") + _accountID + std::string (":") + credentialIndex; + // Default credential already initialized, use credentials.getCredentialCount() + for (i = 0; i < credentials.getCredentialCount(); i++) { - std::string username = Manager::instance().getConfigString (section, USERNAME); - std::string password = Manager::instance().getConfigString (section, PASSWORD); - std::string realm = Manager::instance().getConfigString (section, REALM); + std::string username = _username; + std::string password = _password; + std::string realm = _realm; cred_info[i].username = pj_str (strdup (username.c_str())); cred_info[i].data = pj_str (strdup (password.c_str())); @@ -175,8 +1003,6 @@ int SIPAccount::initCredential (void) _debug ("Setting credential %d realm = %s passwd = %s username = %s data_type = %d", i, realm.c_str(), password.c_str(), username.c_str(), cred_info[i].data_type); } - _credentialCount = credentialCount; - _cred = cred_info; return SUCCESS; @@ -185,10 +1011,10 @@ int SIPAccount::initCredential (void) int SIPAccount::registerVoIPLink() { - _debug ("Register account %s", getAccountID().c_str()); + _debug ("Account: Register account %s", getAccountID().c_str()); // Init general settings - loadConfig(); + // loadConfig(); if (_hostname.length() >= PJ_MAX_HOSTNAME) { return !SUCCESS; @@ -198,19 +1024,19 @@ int SIPAccount::registerVoIPLink() initCredential(); // Init TLS settings if the user wants to use TLS - bool tlsEnabled = Manager::instance().getConfigBool (_accountID, TLS_ENABLE); - - if (tlsEnabled) { + if (_tlsEnable == "true") { + _debug ("Account: TLS is ennabled for accounr %s", getAccountID().c_str()); _transportType = PJSIP_TRANSPORT_TLS; initTlsConfiguration(); } // Init STUN settings for this account if the user selected it - bool stunEnabled = Manager::instance().getConfigBool (_accountID, STUN_ENABLE); - if (stunEnabled) { + if (_stunEnabled) { _transportType = PJSIP_TRANSPORT_START_OTHER; initStunConfiguration (); + } else { + _stunServerName = pj_str ( (char*) _stunServer.data()); } // In our definition of the @@ -267,6 +1093,8 @@ pjsip_ssl_method SIPAccount::sslMethodStringToPjEnum (const std::string& method) void SIPAccount::initTlsConfiguration (void) { + _debug ("SipAccount: Init TLS configuration"); + /* * Initialize structure to zero */ @@ -276,8 +1104,9 @@ void SIPAccount::initTlsConfiguration (void) } // TLS listener is unique and should be only modified through IP2IP_PROFILE - std::string tlsPortStr = Manager::instance().getConfigString (_accountID, TLS_LISTENER_PORT); - setTlsListenerPort (atoi (tlsPortStr.c_str())); + + // setTlsListenerPort(atoi(tlsPortStr.c_str())); + setTlsListenerPort (atoi (_tlsPortStr.c_str())); _tlsSetting = (pjsip_tls_setting *) malloc (sizeof (pjsip_tls_setting)); @@ -285,33 +1114,20 @@ void SIPAccount::initTlsConfiguration (void) pjsip_tls_setting_default (_tlsSetting); - std::string tlsCaListFile = Manager::instance().getConfigString (_accountID, TLS_CA_LIST_FILE); - std::string tlsCertificateFile = Manager::instance().getConfigString (_accountID, TLS_CERTIFICATE_FILE); - std::string tlsPrivateKeyFile = Manager::instance().getConfigString (_accountID, TLS_PRIVATE_KEY_FILE); - std::string tlsPassword = Manager::instance().getConfigString (_accountID, TLS_PASSWORD); - std::string tlsMethod = Manager::instance().getConfigString (_accountID, TLS_METHOD); - std::string tlsCiphers = Manager::instance().getConfigString (_accountID, TLS_CIPHERS); - std::string tlsServerName = Manager::instance().getConfigString (_accountID, TLS_SERVER_NAME); - bool tlsVerifyServer = Manager::instance().getConfigBool (_accountID, TLS_VERIFY_SERVER); - bool tlsVerifyClient = Manager::instance().getConfigBool (_accountID, TLS_VERIFY_CLIENT); - bool tlsRequireClientCertificate = Manager::instance().getConfigBool (_accountID, TLS_REQUIRE_CLIENT_CERTIFICATE); - std::string tlsNegotiationTimeoutSec = Manager::instance().getConfigString (_accountID, TLS_NEGOTIATION_TIMEOUT_SEC); - std::string tlsNegotiationTimeoutMsec = Manager::instance().getConfigString (_accountID, TLS_NEGOTIATION_TIMEOUT_MSEC); - - pj_cstr (&_tlsSetting->ca_list_file, tlsCaListFile.c_str()); - pj_cstr (&_tlsSetting->cert_file, tlsCertificateFile.c_str()); - pj_cstr (&_tlsSetting->privkey_file, tlsPrivateKeyFile.c_str()); - pj_cstr (&_tlsSetting->password, tlsPassword.c_str()); - _tlsSetting->method = sslMethodStringToPjEnum (tlsMethod); - pj_cstr (&_tlsSetting->ciphers, tlsCiphers.c_str()); - pj_cstr (&_tlsSetting->server_name, tlsServerName.c_str()); - - _tlsSetting->verify_server = (tlsVerifyServer == true) ? PJ_TRUE: PJ_FALSE; - _tlsSetting->verify_client = (tlsVerifyClient == true) ? PJ_TRUE: PJ_FALSE; - _tlsSetting->require_client_cert = (tlsRequireClientCertificate == true) ? PJ_TRUE: PJ_FALSE; - - _tlsSetting->timeout.sec = atol (tlsNegotiationTimeoutSec.c_str()); - _tlsSetting->timeout.msec = atol (tlsNegotiationTimeoutMsec.c_str()); + pj_cstr (&_tlsSetting->ca_list_file, _tlsCaListFile.c_str()); + pj_cstr (&_tlsSetting->cert_file, _tlsCertificateFile.c_str()); + pj_cstr (&_tlsSetting->privkey_file, _tlsPrivateKeyFile.c_str()); + pj_cstr (&_tlsSetting->password, _tlsPassword.c_str()); + _tlsSetting->method = sslMethodStringToPjEnum (_tlsMethod); + pj_cstr (&_tlsSetting->ciphers, _tlsCiphers.c_str()); + pj_cstr (&_tlsSetting->server_name, _tlsServerName.c_str()); + + _tlsSetting->verify_server = (_tlsVerifyServer == true) ? PJ_TRUE: PJ_FALSE; + _tlsSetting->verify_client = (_tlsVerifyClient == true) ? PJ_TRUE: PJ_FALSE; + _tlsSetting->require_client_cert = (_tlsRequireClientCertificate == true) ? PJ_TRUE: PJ_FALSE; + + _tlsSetting->timeout.sec = atol (_tlsNegotiationTimeoutSec.c_str()); + _tlsSetting->timeout.msec = atol (_tlsNegotiationTimeoutMsec.c_str()); } @@ -320,8 +1136,7 @@ void SIPAccount::initStunConfiguration (void) size_t pos; std::string stunServer, serverName, serverPort; - stunServer = Manager::instance().getConfigString (_accountID, STUN_SERVER); - + stunServer = _stunServer; // Init STUN socket pos = stunServer.find (':'); @@ -340,51 +1155,10 @@ void SIPAccount::initStunConfiguration (void) void SIPAccount::loadConfig() { - // Load primary credential - setUsername (Manager::instance().getConfigString (_accountID, USERNAME)); - setRouteSet (Manager::instance().getConfigString (_accountID, ROUTESET)); - setPassword (Manager::instance().getConfigString (_accountID, PASSWORD)); - _authenticationUsername = Manager::instance().getConfigString (_accountID, AUTHENTICATION_USERNAME); - _realm = Manager::instance().getConfigString (_accountID, REALM); - _resolveOnce = Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_RESOLVE_ONCE) == "1" ? true : false; - - // Load general account settings - setHostname (Manager::instance().getConfigString (_accountID, HOSTNAME)); - - if (Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE).empty()) { + if (_registrationExpire.empty()) _registrationExpire = DFT_EXPIRE_VALUE; - } else { - _registrationExpire = Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE); - } - - // Load network settings - // Local parameters - - // Load local interface - setLocalInterface (Manager::instance().getConfigString (_accountID, LOCAL_INTERFACE)); - - std::string localPort = Manager::instance().getConfigString (_accountID, LOCAL_PORT); - setLocalPort (atoi (localPort.c_str())); - - - // Published parameters - setPublishedSameasLocal (Manager::instance().getConfigString (_accountID, PUBLISHED_SAMEAS_LOCAL) == TRUE_STR ? true : false); - - std::string publishedPort = Manager::instance().getConfigString (_accountID, PUBLISHED_PORT); - setPublishedPort (atoi (publishedPort.c_str())); - - setPublishedAddress (Manager::instance().getConfigString (_accountID, PUBLISHED_ADDRESS)); - - if (Manager::instance().getConfigString (_accountID, ACCOUNT_DTMF_TYPE) == OVERRTPSTR) - _dtmfType = OVERRTP; - else - _dtmfType = SIPINFO; - - // Init TLS settings if the user wants to use TLS - bool tlsEnabled = Manager::instance().getConfigBool (_accountID, TLS_ENABLE); - - if (tlsEnabled) { + if (_tlsEnable == "true") { initTlsConfiguration(); _transportType = PJSIP_TRANSPORT_TLS; } else { @@ -579,8 +1353,6 @@ std::string SIPAccount::getContactHeader (const std::string& address, const std: transport = ""; } - _displayName = Manager::instance().getConfigString (_accountID, DISPLAY_NAME); - _debug ("Display Name: %s", _displayName.c_str()); int len = pj_ansi_snprintf (contact, PJSIP_MAX_URL_SIZE, diff --git a/sflphone-common/src/sip/sipaccount.h b/sflphone-common/src/sip/sipaccount.h index 51fb6de0c451eaffd5642f2b4824f15384ab14e0..6453d8f9b6823f7437c8107a93ae5909700cf82a 100644 --- a/sflphone-common/src/sip/sipaccount.h +++ b/sflphone-common/src/sip/sipaccount.h @@ -10,12 +10,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -41,12 +41,62 @@ #include "sipvoiplink.h" #include "pjsip/sip_transport_tls.h" #include "pjsip/sip_types.h" +#include "config/serializable.h" +#include <exception> +#include <map> enum DtmfType { OVERRTP, SIPINFO}; #define OVERRTPSTR "overrtp" #define SIPINFOSTR "sipinfo" + +// SIP specific configuration keys +const Conf::Key expireKey ("expire"); +const Conf::Key interfaceKey ("interface"); +const Conf::Key portKey ("port"); +const Conf::Key publishAddrKey ("publishAddr"); +const Conf::Key publishPortKey ("publishPort"); +const Conf::Key sameasLocalKey ("sameasLocal"); +const Conf::Key resolveOnceKey ("resolveOnce"); +const Conf::Key dtmfTypeKey ("dtmfType"); +const Conf::Key serviceRouteKey ("serviceRoute"); + +// TODO: write an object to store credential which implement serializable +const Conf::Key srtpKey ("srtp"); +const Conf::Key srtpEnableKey ("enable"); +const Conf::Key keyExchangeKey ("keyExchange"); +const Conf::Key rtpFallbackKey ("rtpFallback"); + +// TODO: wirte an object to store zrtp params wich implement serializable +const Conf::Key zrtpKey ("zrtp"); +const Conf::Key displaySasKey ("displaySas"); +const Conf::Key displaySasOnceKey ("displaySasOnce"); +const Conf::Key helloHashEnabledKey ("helloHashEnabled"); +const Conf::Key notSuppWarningKey ("notSuppWarning"); + +// TODO: write an object to store tls params which implement serializable +const Conf::Key tlsKey ("tls"); +const Conf::Key tlsPortKey ("tlsPort"); +const Conf::Key certificateKey ("certificate"); +const Conf::Key calistKey ("calist"); +const Conf::Key ciphersKey ("ciphers"); +const Conf::Key tlsEnableKey ("enable"); +const Conf::Key methodKey ("method"); +const Conf::Key timeoutKey ("timeout"); +const Conf::Key tlsPasswordKey ("password"); +const Conf::Key privateKeyKey ("privateKey"); +const Conf::Key requireCertifKey ("requireCertif"); +const Conf::Key serverKey ("server"); +const Conf::Key verifyClientKey ("verifyClient"); +const Conf::Key verifyServerKey ("verifyServer"); + +const Conf::Key stunEnabledKey ("stunEnabled"); +const Conf::Key stunServerKey ("stunServer"); + +const Conf::Key credKey ("credential"); +const Conf::Key credentialCountKey ("count"); + class SIPVoIPLink; /** @@ -54,6 +104,65 @@ class SIPVoIPLink; * @brief A SIP Account specify SIP specific functions and object (SIPCall/SIPVoIPLink) */ +class SipAccountException : public std::exception +{ + public: + SipAccountException (const std::string& str="") throw() : errstr (str) {} + + virtual ~SipAccountException() throw() {} + + virtual const char *what() const throw() { + std::string expt ("SipAccountException occured: "); + expt.append (errstr); + + return expt.c_str(); + } + private: + std::string errstr; + +}; + +class CredentialItem +{ + public: + + std::string username; + std::string password; + std::string realm; +}; + + +class Credentials : public Serializable +{ + public: + + Credentials(); + + ~Credentials(); + + virtual void serialize (Conf::YamlEmitter *emitter); + + virtual void unserialize (Conf::MappingNode *map); + + int getCredentialCount (void) { + return credentialCount; + } + void setCredentialCount (int count) { + credentialCount = count; + } + + void setNewCredential (std::string username, std::string password, std::string realm); + CredentialItem *getCredential (int index); + + private: + + int credentialCount; + + CredentialItem credentialArray[10]; + +}; + + class SIPAccount : public Account { public: @@ -61,43 +170,55 @@ class SIPAccount : public Account * Constructor * @param accountID The account identifier */ - SIPAccount(const AccountID& accountID); + SIPAccount (const AccountID& accountID); /* Copy Constructor */ - SIPAccount(const SIPAccount& rh); + SIPAccount (const SIPAccount& rh); /* Assignment Operator */ - SIPAccount& operator=( const SIPAccount& rh); + SIPAccount& operator= (const SIPAccount& rh); /** * Virtual destructor */ virtual ~SIPAccount(); - /** - * Set route header to appears in sip messages for this account - */ - void setRouteSet(std::string route) { _routeSet = route; } + virtual void serialize (Conf::YamlEmitter *emitter); + + virtual void unserialize (Conf::MappingNode *map); + + virtual void setAccountDetails (const std::map<std::string, std::string>& details); - /** - * Get route header to appear in sip messages for this account - */ - std::string getRouteSet(void) { return _routeSet; } + virtual std::map<std::string, std::string> getAccountDetails(); - /** - * Special setVoIPLink which increment SipVoIPLink's number of client. - */ - // void setVoIPLink(VoIPLink *link); - void setVoIPLink(); + /** + * Set route header to appears in sip messages for this account + */ + void setRouteSet (std::string route) { + _routeSet = route; + } - /** - * Actually useless, since config loading is done in init() + /** + * Get route header to appear in sip messages for this account + */ + std::string getRouteSet (void) { + return _routeSet; + } + + /** + * Special setVoIPLink which increment SipVoIPLink's number of client. + */ + // void setVoIPLink(VoIPLink *link); + void setVoIPLink(); + + /** + * Actually useless, since config loading is done in init() */ void loadConfig(); /** * Initialize the SIP voip link with the account parameters and send registration - */ + */ int registerVoIPLink(); /** @@ -105,100 +226,150 @@ class SIPAccount : public Account */ int unregisterVoIPLink(); - inline void setCredInfo(pjsip_cred_info *cred) {_cred = cred;} - inline pjsip_cred_info *getCredInfo() {return _cred;} - - inline std::string& getAuthenticationUsername(void) { return _authenticationUsername; } - inline void setAuthenticationUsername(const std::string& username) { _authenticationUsername = username; } - - inline bool isResolveOnce(void) { return _resolveOnce; } - - - /** - * A client sendings a REGISTER request MAY suggest an expiration - * interval that indicates how long the client would like the - * registration to be valid. - * - * @return A string describing the expiration value. - */ - inline std::string& getRegistrationExpire(void) { return _registrationExpire; } - - /** - * Setting the Expiration Interval of Contact Addresses. - * - * @param A string describing the expiration value. - */ - inline void setRegistrationExpire(std::string expr) { _registrationExpire = expr; } - - bool fullMatch(const std::string& username, const std::string& hostname); - bool userMatch(const std::string& username); - bool hostnameMatch(const std::string& hostname); - + inline void setCredInfo (pjsip_cred_info *cred) { + _cred = cred; + } + inline pjsip_cred_info *getCredInfo() { + return _cred; + } + + inline std::string& getAuthenticationUsername (void) { + return _authenticationUsername; + } + inline void setAuthenticationUsername (const std::string& username) { + _authenticationUsername = username; + } + + inline bool isResolveOnce (void) { + return _resolveOnce; + } + void setResolveOnce (bool reslv) { + _resolveOnce = reslv; + } + + + /** + * A client sendings a REGISTER request MAY suggest an expiration + * interval that indicates how long the client would like the + * registration to be valid. + * + * @return A string describing the expiration value. + */ + inline std::string& getRegistrationExpire (void) { + return _registrationExpire; + } + + /** + * Setting the Expiration Interval of Contact Addresses. + * + * @param A string describing the expiration value. + */ + inline void setRegistrationExpire (std::string expr) { + _registrationExpire = expr; + } + + bool fullMatch (const std::string& username, const std::string& hostname); + bool userMatch (const std::string& username); + bool hostnameMatch (const std::string& hostname); + /* Registration flag */ - bool isRegister() {return _bRegister;} - void setRegister(bool result) {_bRegister = result;} - + bool isRegister() { + return _bRegister; + } + void setRegister (bool result) { + _bRegister = result; + } + /** - * Get the registration stucture that is used + * Get the registration stucture that is used * for PJSIP in the registration process. * Settings are loaded from configuration file. * @param void * @return pjsip_regc* A pointer to the registration structure */ - pjsip_regc* getRegistrationInfo( void ) { return _regc; } - - /** + pjsip_regc* getRegistrationInfo (void) { + return _regc; + } + + /** * Set the registration structure that is used * for PJSIP in the registration process; * @pram A pointer to the new registration structure * @return void */ - void setRegistrationInfo( pjsip_regc *regc ) { _regc = regc; } + void setRegistrationInfo (pjsip_regc *regc) { + _regc = regc; + } /** - * Get the number of credentials defined for + * Get the number of credentials defined for * this account. * @param none * @return int The number of credentials set for this account. */ - inline int getCredentialCount(void) { return _credentialCount; } - + inline int getCredentialCount (void) { + return credentials.getCredentialCount() + 1; + } + inline void setCredentialCount (int count) { + return credentials.setCredentialCount (count); + } + /** * @return pjsip_tls_setting structure, filled from the configuration - * file, that can be used directly by PJSIP to initialize + * file, that can be used directly by PJSIP to initialize * TLS transport. */ - inline pjsip_tls_setting * getTlsSetting(void) { return _tlsSetting; } - - /** + inline pjsip_tls_setting * getTlsSetting (void) { + return _tlsSetting; + } + + /** * @return pj_str_t , filled from the configuration - * file, that can be used directly by PJSIP to initialize + * file, that can be used directly by PJSIP to initialize * an alternate UDP transport. */ - inline pj_str_t getStunServerName(void) { return _stunServerName; } - inline void setStunServerName (pj_str_t srv) { _stunServerName = srv; } + inline std::string getStunServer (void) { + return _stunServer; + } + inline void setStunServer (std::string srv) { + _stunServer = srv; + } + + inline pj_str_t getStunServerName (void) { + return _stunServerName; + } - /** + /** * @return pj_uint8_t structure, filled from the configuration - * file, that can be used directly by PJSIP to initialize + * file, that can be used directly by PJSIP to initialize * an alternate UDP transport. */ - inline pj_uint16_t getStunPort (void) { return _stunPort; } - inline void setStunPort (pj_uint16_t port) { _stunPort = port; } - + inline pj_uint16_t getStunPort (void) { + return _stunPort; + } + inline void setStunPort (pj_uint16_t port) { + _stunPort = port; + } + /** - * @return bool Tells if current transport for that + * @return bool Tells if current transport for that * account is set to TLS. */ - inline bool isTlsEnabled(void) { return (_transportType == PJSIP_TRANSPORT_TLS) ? true: false; } - - /** - * @return bool Tells if current transport for that - * account is set to OTHER. - */ - inline bool isStunEnabled(void) { return (_transportType == PJSIP_TRANSPORT_START_OTHER) ? true: false; } - - + inline bool isTlsEnabled (void) { + return (_transportType == PJSIP_TRANSPORT_TLS) ? true: false; + } + + /** + * @return bool Tells if current transport for that + * account is set to OTHER. + */ + inline bool isStunEnabled (void) { + return (_transportType == PJSIP_TRANSPORT_START_OTHER) ? true: false; + } + inline void setStunEnabled (bool enabl) { + _stunEnabled = enabl; + } + /* * @return pj_str_t "From" uri based on account information. * From RFC3261: "The To header field first and foremost specifies the desired @@ -208,8 +379,8 @@ class SIPAccount : public Account * of the host on which the UA is running, since these are not logical * names." */ - std::string getFromUri(void); - + std::string getFromUri (void); + /* * This method adds the correct scheme, hostname and append * the ;transport= parameter at the end of the uri, in accordance with RFC3261. @@ -218,169 +389,358 @@ class SIPAccount : public Account * @return pj_str_t "To" uri based on @param username * @param username A string formatted as : "username" */ - std::string getToUri(const std::string& username); + std::string getToUri (const std::string& username); /* - * In the current version of SFLPhone, "srv" uri is obtained in the preformated + * In the current version of SFLPhone, "srv" uri is obtained in the preformated * way: hostname:port. This method adds the correct scheme and append * the ;transport= parameter at the end of the uri, in accordance with RFC3261. * * @return pj_str_t "server" uri based on @param hostPort * @param hostPort A string formatted as : "hostname:port" */ - std::string getServerUri(void); - + std::string getServerUri (void); + /** * @param port Optional port. Otherwise set to the port defined for that account. * @param hostname Optional local address. Otherwise set to the hostname defined for that account. * @return pj_str_t The contact header based on account information */ - std::string getContactHeader(const std::string& address, const std::string& port); + std::string getContactHeader (const std::string& address, const std::string& port); - /** - * Set the interface name on which this account is bound, "default" means - * that the account is bound to the ANY interafec (0.0.0.0). This method should be - * when binding the account to a new sip transport only. - */ - inline void setLocalInterface(const std::string& interface) {_interface = interface;} + /** + * Set the interface name on which this account is bound, "default" means + * that the account is bound to the ANY interafec (0.0.0.0). This method should be + * when binding the account to a new sip transport only. + */ + inline void setLocalInterface (const std::string& interface) { + _interface = interface; + } - /** - * Get the local interface name on which this account is bound. - */ - inline std::string getLocalInterface(void) { return _interface; } + /** + * Get the local interface name on which this account is bound. + */ + inline std::string getLocalInterface (void) { + return _interface; + } - /** - * Get a flag which determine the usage in sip headers of either the local - * IP address and port (_localAddress and _localPort) or to an address set - * manually (_publishedAddress and _publishedPort). - */ - bool getPublishedSameasLocal(){ return _publishedSameasLocal; } + /** + * Get a flag which determine the usage in sip headers of either the local + * IP address and port (_localAddress and _localPort) or to an address set + * manually (_publishedAddress and _publishedPort). + */ + bool getPublishedSameasLocal() { + return _publishedSameasLocal; + } - /** - * Set a flag which determine the usage in sip headers of either the local - * IP address and port (_localAddress and _localPort) or to an address set - * manually (_publishedAddress and _publishedPort). - */ - void setPublishedSameasLocal(bool published){ _publishedSameasLocal = published; } + /** + * Set a flag which determine the usage in sip headers of either the local + * IP address and port (_localAddress and _localPort) or to an address set + * manually (_publishedAddress and _publishedPort). + */ + void setPublishedSameasLocal (bool published) { + _publishedSameasLocal = published; + } /** * Get the port on which the transport/listener should use, or is * actually using. * @return pj_uint16 The port used for that account - */ - inline pj_uint16_t getLocalPort(void) { return (pj_uint16_t) _localPort; } - - /** + */ + inline pj_uint16_t getLocalPort (void) { + return (pj_uint16_t) _localPort; + } + + /** * Set the new port on which this account is running over. * @pram port The port used by this account. */ - inline void setLocalPort(pj_uint16_t port) { _localPort = port; } - + inline void setLocalPort (pj_uint16_t port) { + _localPort = port; + } + /** * Get the published port, which is the port to be advertised as the port * for the chosen SIP transport. * @return pj_uint16 The port used for that account - */ - inline pj_uint16_t getPublishedPort(void) { return (pj_uint16_t) _publishedPort; } - - /** + */ + inline pj_uint16_t getPublishedPort (void) { + return (pj_uint16_t) _publishedPort; + } + + /** * Set the published port, which is the port to be advertised as the port * for the chosen SIP transport. * @pram port The port used by this account. */ - inline void setPublishedPort(pj_uint16_t port) { _publishedPort = port; } + inline void setPublishedPort (pj_uint16_t port) { + _publishedPort = port; + } - /** - * Get the local port for TLS listener. - * @return pj_uint16 The port used for that account - */ - inline pj_uint16_t getTlsListenerPort(void) { return (pj_uint16_t) _tlsListenerPort; } - - /** + /** + * Get the local port for TLS listener. + * @return pj_uint16 The port used for that account + */ + inline pj_uint16_t getTlsListenerPort (void) { + return (pj_uint16_t) _tlsListenerPort; + } + + /** * Set the local port for TLS listener. * @pram port The port used for TLS listener. */ - inline void setTlsListenerPort(pj_uint16_t port) { _tlsListenerPort = port; } - + inline void setTlsListenerPort (pj_uint16_t port) { + _tlsListenerPort = port; + } + /** * Get the public IP address set by the user for this account. * If this setting is not provided, the local bound adddress * will be used. * @return std::string The public IPV4 address formatted in the standard dot notation. */ - inline std::string getPublishedAddress(void) { return _publishedIpAddress; } - + inline std::string getPublishedAddress (void) { + return _publishedIpAddress; + } + /** * Set the public IP address to be used in Contact header. * @param The public IPV4 address in the standard dot notation. * @return void */ - inline void setPublishedAddress(const std::string& publishedIpAddress) { _publishedIpAddress = publishedIpAddress; } - + inline void setPublishedAddress (const std::string& publishedIpAddress) { + _publishedIpAddress = publishedIpAddress; + } + + inline std::string getServiceRoute (void) { + return _serviceRoute; + } + + inline void setServiceRoute (std::string route) { + _serviceRoute = route; + } + /** * Get the chosen transport type. * @return pjsip_transport_type_e Transport type chosen by the user for this account. */ - inline pjsip_transport_type_e getTransportType(void) { return _transportType; } - - inline pjsip_transport* getAccountTransport (void) { return _transport; } - - inline void setAccountTransport (pjsip_transport *transport) { _transport = transport; } - - std::string getTransportMapKey(void); - - DtmfType getDtmfType(void) { return _dtmfType; } - - void setDtmfType(DtmfType type) { _dtmfType = type; } - - private: - - /* Maps a string description of the SSL method + inline pjsip_transport_type_e getTransportType (void) { + return _transportType; + } + + inline pjsip_transport* getAccountTransport (void) { + return _transport; + } + + inline void setAccountTransport (pjsip_transport *transport) { + _transport = transport; + } + + std::string getTransportMapKey (void); + + DtmfType getDtmfType (void) { + return _dtmfType; + } + void setDtmfType (DtmfType type) { + _dtmfType = type; + } + + bool getSrtpEnable (void) { + return _srtpEnabled; + } + void setSrtpEnable (bool enabl) { + _srtpEnabled = enabl; + } + + std::string getSrtpKeyExchange (void) { + return _srtpKeyExchange; + } + void setSrtpKeyExchange (std::string key) { + _srtpKeyExchange = key; + } + + bool getSrtpFallback (void) { + return _srtpFallback; + } + void setSrtpFallback (bool fallback) { + _srtpFallback = fallback; + } + + bool getZrtpDisplaySas (void) { + return _zrtpDisplaySas; + } + void setZrtpDisplaySas (bool sas) { + _zrtpDisplaySas = sas; + } + + bool getZrtpDiaplaySasOnce (void) { + return _zrtpDisplaySasOnce; + } + void setZrtpDiaplaySasOnce (bool sasonce) { + _zrtpDisplaySasOnce = sasonce; + } + + bool getZrtpNotSuppWarning (void) { + return _zrtpNotSuppWarning; + } + void setZrtpNotSuppWarning (bool warning) { + _zrtpNotSuppWarning = warning; + } + + bool getZrtpHelloHash (void) { + return _zrtpHelloHash; + } + void setZrtpHelloHash (bool hellohash) { + _zrtpHelloHash = hellohash; + } + // void setSrtpKeyExchange + + std::string getRealm (void) { + return _realm; + } + void setRealm (std::string r) { + _realm = r; + } + + std::string getTlsEnable (void) { + return _tlsEnable; + } + void setTlsEnable (std::string enabl) { + _tlsEnable = enabl; + } + + std::string getTlsCaListFile (void) { + return _tlsCaListFile; + } + void setTlsCaListFile (std::string calist) { + _tlsCaListFile = calist; + } + + std::string getTlsCertificateFile (void) { + return _tlsCertificateFile; + } + void setTlsCertificateFile (std::string cert) { + _tlsCertificateFile = cert; + } + + std::string getTlsPrivateKeyFile (void) { + return _tlsPrivateKeyFile; + } + void setTlsPrivateKeyFile (std::string priv) { + _tlsPrivateKeyFile = priv; + } + + std::string getTlsPassword (void) { + return _tlsPassword; + } + void setTlsPassword (std::string pass) { + _tlsPassword = pass; + } + + std::string getTlsMethod (void) { + return _tlsMethod; + } + void setTlsMethod (std::string meth) { + _tlsMethod = meth; + } + + std::string getTlsCiphers (void) { + return _tlsCiphers; + } + void setTlsCiphers (std::string cipher) { + _tlsCiphers = cipher; + } + + std::string getTlsServerName (void) { + return _tlsServerName; + } + void setTlsServerName (std::string name) { + _tlsServerName = name; + } + + bool getTlsVerifyServer (void) { + return _tlsVerifyServer; + } + void setTlsVerifyServer (bool verif) { + _tlsVerifyServer = verif; + } + + bool getTlsVerifyClient (void) { + return _tlsVerifyClient; + } + void setTlsVerifyClient (bool verif) { + _tlsVerifyClient = verif; + } + + bool getTlsRequireClientCertificate (void) { + return _tlsRequireClientCertificate; + } + void setTlsRequireClientCertificate (bool require) { + _tlsRequireClientCertificate = require; + } + + std::string getTlsNegotiationTimeoutSec (void) { + return _tlsNegotiationTimeoutSec; + } + void setTlsNegotiationTimeoutSec (std::string timeout) { + _tlsNegotiationTimeoutSec = timeout; + } + + std::string getTlsNegotiationTimeoutMsec (void) { + return _tlsNegotiationTimeoutMsec; + } + void setTlsNegotiationTimeoutMsec (std::string timeout) { + _tlsNegotiationTimeoutMsec = timeout; + } + + private: + + /* Maps a string description of the SSL method * to the corresponding enum value in pjsip_ssl_method. - * @param method The string representation + * @param method The string representation * @return pjsip_ssl_method The corresponding value in the enum */ - pjsip_ssl_method sslMethodStringToPjEnum(const std::string& method); - + pjsip_ssl_method sslMethodStringToPjEnum (const std::string& method); + /* * Initializes tls settings from configuration file. * - */ - void initTlsConfiguration(void); - - /* - * Initializes STUN config from the config file - */ - void initStunConfiguration (void); - + */ + void initTlsConfiguration (void); + + /* + * Initializes STUN config from the config file + */ + void initStunConfiguration (void); + /* * Initializes set of additional credentials, if supplied by the user. */ - int initCredential(void); - + int initCredential (void); + /** - * If username is not provided, as it happens for Direct ip calls, + * If username is not provided, as it happens for Direct ip calls, * fetch the hostname of the machine on which the program is running * onto. * @return std::string The machine hostname as returned by pj_gethostname() */ - std::string getMachineName(void); - + std::string getMachineName (void); + /** - * If username is not provided, as it happens for Direct ip calls, - * fetch the Real Name field of the user that is currently - * running this program. + * If username is not provided, as it happens for Direct ip calls, + * fetch the Real Name field of the user that is currently + * running this program. * @return std::string The login name under which SFLPhone is running. - */ - std::string getLoginName(void); + */ + std::string getLoginName (void); + + std::string _routeSet; - std::string _routeSet; - // The pjsip client registration information pjsip_regc *_regc; // To check if the account is registered - bool _bRegister; + bool _bRegister; // Network settings std::string _registrationExpire; @@ -391,45 +751,73 @@ class SIPAccount : public Account // Flag which determine if _localIpAddress or _publishedIpAddress is used in // sip headers bool _publishedSameasLocal; - + std::string _publishedIpAddress; - + pj_uint16_t _localPort; pj_uint16_t _publishedPort; + std::string _serviceRoute; + /** * The global TLS listener port which can be configured through the IP2IP_PROFILE */ pj_uint16_t _tlsListenerPort; - + pjsip_transport_type_e _transportType; - pjsip_transport* _transport; + pjsip_transport* _transport; // Special hack that is not here to stay // See #1852 bool _resolveOnce; - + //Credential information - int _credentialCount; - pjsip_cred_info *_cred; - std::string _realm; + pjsip_cred_info *_cred; + std::string _realm; std::string _authenticationUsername; + Credentials credentials; - // The TLS settings, if tls is chosen as - // a sip transport. - pjsip_tls_setting * _tlsSetting; + // The TLS settings, if tls is chosen as + // a sip transport. + pjsip_tls_setting * _tlsSetting; - // The STUN server name, if applicable - pj_str_t _stunServerName; + // The STUN server name, if applicable for internal use only + pj_str_t _stunServerName; // The STUN server port, if applicable pj_uint16_t _stunPort; DtmfType _dtmfType; - - // Display Name that can be used in SIP URI. - std::string _displayName; + + std::string _tlsEnable; + std::string _tlsPortStr; + std::string _tlsCaListFile; + std::string _tlsCertificateFile; + std::string _tlsPrivateKeyFile; + std::string _tlsPassword; + std::string _tlsMethod; + std::string _tlsCiphers; + std::string _tlsServerName; + bool _tlsVerifyServer; + bool _tlsVerifyClient; + bool _tlsRequireClientCertificate; + std::string _tlsNegotiationTimeoutSec; + std::string _tlsNegotiationTimeoutMsec; + + std::string _stunServer; + bool _stunEnabled; + + bool _srtpEnabled; + std::string _srtpKeyExchange; + bool _srtpFallback; + + bool _zrtpDisplaySas; + bool _zrtpDisplaySasOnce; + bool _zrtpHelloHash; + bool _zrtpNotSuppWarning; + + }; #endif diff --git a/sflphone-common/src/sip/sipcall.h b/sflphone-common/src/sip/sipcall.h index 46af03ad2d046c2338d4f8fd404b90103b249c5a..5c4eb4cf5f153184f52934e3c830c6c80f290ade 100644 --- a/sflphone-common/src/sip/sipcall.h +++ b/sflphone-common/src/sip/sipcall.h @@ -43,105 +43,132 @@ class AudioCodec; class Sdp; class AudioRtp; -namespace sfl { - class AudioRtpFactory; +namespace sfl +{ +class AudioRtpFactory; } /** * @file sipcall.h - * @brief SIPCall are SIP implementation of a normal Call + * @brief SIPCall are SIP implementation of a normal Call */ class SIPCall : public Call { - public: - - /** - * Constructor - * @param id The call identifier - * @param type The type of the call. Could be Incoming - * Outgoing - */ - SIPCall(const CallID& id, Call::CallType type, pj_pool_t *pool ); - - /** - * Destructor - */ - ~SIPCall(); - - /** - * Call Identifier - * @return int SIP call id - */ - int getCid() { return _cid; } - - /** - * Call Identifier - * @param cid SIP call id - */ - void setCid(int cid) { _cid = cid ; } - - /** - * Domain identifier - * @return int SIP domain id - */ - int getDid() { return _did; } - - /** - * Domain identifier - * @param did SIP domain id - */ - void setDid(int did) { _did = did; } - - /** - * Transaction identifier - * @return int SIP transaction id - */ - int getTid() { return _tid; } - - - - - /** - * Transaction identifier - * @param tid SIP transaction id - */ - void setTid(int tid) { _tid = tid; } - - void setXferSub(pjsip_evsub* sub) {_xferSub = sub;} - - pjsip_evsub *getXferSub() {return _xferSub;} - - void setInvSession(pjsip_inv_session* inv) {_invSession = inv;} - - pjsip_inv_session *getInvSession() {return _invSession;} - - Sdp* getLocalSDP (void) { return _local_sdp; } - - void setLocalSDP (Sdp *local_sdp) { _local_sdp = local_sdp; } - - /** Returns a pointer to the AudioRtp object */ - inline sfl::AudioRtpFactory * getAudioRtp(void) { return _audiortp; } - - private: - - int _cid; - int _did; - int _tid; - - // Copy Constructor - SIPCall(const SIPCall& rh); - - // Assignment Operator - SIPCall& operator=( const SIPCall& rh); - - /** Starting sound */ - sfl::AudioRtpFactory * _audiortp; - - pjsip_evsub *_xferSub; - - pjsip_inv_session *_invSession; - - Sdp *_local_sdp; + public: + + /** + * Constructor + * @param id The call identifier + * @param type The type of the call. Could be Incoming + * Outgoing + */ + SIPCall (const CallID& id, Call::CallType type, pj_pool_t *pool); + + /** + * Destructor + */ + ~SIPCall(); + + /** + * Call Identifier + * @return int SIP call id + */ + int getCid() { + return _cid; + } + + /** + * Call Identifier + * @param cid SIP call id + */ + void setCid (int cid) { + _cid = cid ; + } + + /** + * Domain identifier + * @return int SIP domain id + */ + int getDid() { + return _did; + } + + /** + * Domain identifier + * @param did SIP domain id + */ + void setDid (int did) { + _did = did; + } + + /** + * Transaction identifier + * @return int SIP transaction id + */ + int getTid() { + return _tid; + } + + + + + /** + * Transaction identifier + * @param tid SIP transaction id + */ + void setTid (int tid) { + _tid = tid; + } + + void setXferSub (pjsip_evsub* sub) { + _xferSub = sub; + } + + pjsip_evsub *getXferSub() { + return _xferSub; + } + + void setInvSession (pjsip_inv_session* inv) { + _invSession = inv; + } + + pjsip_inv_session *getInvSession() { + return _invSession; + } + + Sdp* getLocalSDP (void) { + return _local_sdp; + } + + void setLocalSDP (Sdp *local_sdp) { + _local_sdp = local_sdp; + } + + /** Returns a pointer to the AudioRtp object */ + inline sfl::AudioRtpFactory * getAudioRtp (void) { + return _audiortp; + } + + private: + + int _cid; + int _did; + int _tid; + + // Copy Constructor + SIPCall (const SIPCall& rh); + + // Assignment Operator + SIPCall& operator= (const SIPCall& rh); + + /** Starting sound */ + sfl::AudioRtpFactory * _audiortp; + + pjsip_evsub *_xferSub; + + pjsip_inv_session *_invSession; + + Sdp *_local_sdp; }; diff --git a/sflphone-common/src/sip/sipvoiplink.cpp b/sflphone-common/src/sip/sipvoiplink.cpp index b5985d51305ecd58717dafc66fdb92b3360e74ae..2c520811a7bd7a0df4abab1218bc8006c50768d7 100644 --- a/sflphone-common/src/sip/sipvoiplink.cpp +++ b/sflphone-common/src/sip/sipvoiplink.cpp @@ -273,6 +273,8 @@ SIPVoIPLink::SIPVoIPLink (const AccountID& accountID) , _regPort (atoi (DEFAULT_SIP_PORT)) , _clients (0) { + + _debug ("SIPVOIPLINK"); // to get random number for RANDOM_PORT srand (time (NULL)); @@ -456,9 +458,12 @@ std::string SIPVoIPLink::get_useragent_name (const AccountID& id) useragent << PROGNAME << "/" << SFLPHONED_VERSION; return useragent.str(); */ + + SIPAccount *account = (SIPAccount *) Manager::instance().getAccount (id); + std::ostringstream useragent; - useragent << Manager::instance ().getConfigString (id, USERAGENT); + useragent << account->getUseragent(); if (useragent.str() == "sflphone" || useragent.str() == "") useragent << "/" << SFLPHONED_VERSION; @@ -598,7 +603,7 @@ int SIPVoIPLink::sendRegister (AccountID id) std::string contactUri = account->getContactHeader (address, portStr); - _debug ("sendRegister: fromUri: %s serverUri: %s contactUri: %s", + _debug ("UserAgent: sendRegister: fromUri: %s serverUri: %s contactUri: %s", fromUri.c_str(), srvUri.c_str(), contactUri.c_str()); @@ -615,31 +620,24 @@ int SIPVoIPLink::sendRegister (AccountID id) // Initializes registration // Set Route for registration passing throught one or several proxies - status = pjsip_regc_init (regc, &pjSrv, &pjFrom, &pjFrom, 1, &pjContact, expire_value); - - /* - if(!(account->getDomainName().empty())) { + // status = pjsip_regc_init (regc, &pjSrv, &pjFrom, &pjFrom, 1, &pjContact, expire_value); - _error("Set route with %s", account->getHostname().c_str()); + status = pjsip_regc_init (regc, &pjSrv, &pjFrom, &pjFrom, 1, &pjContact, expire_value); - pjsip_route_hdr *route_set = pjsip_route_hdr_create(_pool); - pjsip_route_hdr *routing = pjsip_route_hdr_create(_pool); - pjsip_sip_uri *url = pjsip_sip_uri_create(_pool, 0); - routing->name_addr.uri = (pjsip_uri*)url; - pj_strdup2(_pool, &url->host, account->getHostname().c_str()); + if (! (account->getServiceRoute().empty())) { - pj_list_push_back(&route_set, pjsip_hdr_clone(_pool, routing)); + _error ("UserAgent: Set Service-Route with %s", account->getServiceRoute().c_str()); - status = pjsip_regc_init (regc, &pjSrv, &pjFrom, &pjFrom, 1, &pjContact, expire_value); + pjsip_route_hdr *route_set = pjsip_route_hdr_create (_pool); + pjsip_route_hdr *routing = pjsip_route_hdr_create (_pool); + pjsip_sip_uri *url = pjsip_sip_uri_create (_pool, 0); + routing->name_addr.uri = (pjsip_uri*) url; + pj_strdup2 (_pool, &url->host, account->getServiceRoute().c_str()); - pjsip_regc_set_route_set(regc, route_set); - } - else { + pj_list_push_back (&route_set, pjsip_hdr_clone (_pool, routing)); - status = pjsip_regc_init (regc, &pjSrv, &pjFrom, &pjFrom, 1, &pjContact, expire_value); + pjsip_regc_set_route_set (regc, route_set); } - */ - if (status != PJ_SUCCESS) { _debug ("UserAgent: Unable to initialize account %d in sendRegister", status); @@ -650,7 +648,7 @@ int SIPVoIPLink::sendRegister (AccountID id) pjsip_cred_info *cred = account->getCredInfo(); int credential_count = account->getCredentialCount(); - _debug ("setting %d credentials in sendRegister", credential_count); + _debug ("UserAgent: setting %d credentials in sendRegister", credential_count); pjsip_regc_set_credentials (regc, credential_count, cred); // Add User-Agent Header @@ -685,7 +683,7 @@ int SIPVoIPLink::sendRegister (AccountID id) // managed when acquiring transport pjsip_transport_dec_ref (account->getAccountTransport ()); - _debug ("After setting the transport in account registration using transport: %s %s (refcnt=%d)", + _debug ("UserAgent: After setting the transport in account registration using transport: %s %s (refcnt=%d)", account->getAccountTransport()->obj_name, account->getAccountTransport()->info, (int) pj_atomic_get (account->getAccountTransport()->ref_cnt)); @@ -1369,7 +1367,7 @@ SIPVoIPLink::dtmfSipInfo (SIPCall *call, char code) pjsip_media_type ctype; - duration = Manager::instance().getConfigInt (SIGNALISATION, PULSE_LENGTH); + duration = Manager::instance().voipPreferences.getPulseLength(); dtmf_body = new char[body_len]; @@ -1509,6 +1507,23 @@ SIPVoIPLink::SIPStartCall (SIPCall* call, const std::string& subject UNUSED) // Create the invite session for this call status = pjsip_inv_create_uac (dialog, call->getLocalSDP()->get_local_sdp_session(), 0, &inv); + + if (! (account->getServiceRoute().empty())) { + + _error ("UserAgent: Set Service-Route with %s", account->getServiceRoute().c_str()); + + pjsip_route_hdr *route_set = pjsip_route_hdr_create (_pool); + pjsip_route_hdr *routing = pjsip_route_hdr_create (_pool); + pjsip_sip_uri *url = pjsip_sip_uri_create (_pool, 0); + routing->name_addr.uri = (pjsip_uri*) url; + pj_strdup2 (_pool, &url->host, account->getServiceRoute().c_str()); + + pj_list_push_back (&route_set, pjsip_hdr_clone (_pool, routing)); + + pjsip_dlg_set_route_set (dialog, route_set); + } + + PJ_ASSERT_RETURN (status == PJ_SUCCESS, false); // Set auth information @@ -1613,7 +1628,7 @@ SIPVoIPLink::SIPCallReleased (SIPCall *call) void -SIPVoIPLink::SIPCallAnswered (SIPCall *call, pjsip_rx_data *rdata) +SIPVoIPLink::SIPCallAnswered (SIPCall *call, pjsip_rx_data *rdata UNUSED) { _info ("UserAgent: SIP call answered"); @@ -1775,6 +1790,21 @@ bool SIPVoIPLink::new_ip_to_ip_call (const CallID& id, const std::string& to) status = pjsip_inv_create_uac (dialog, call->getLocalSDP()->get_local_sdp_session(), 0, &inv); PJ_ASSERT_RETURN (status == PJ_SUCCESS, false); + if (! (account->getServiceRoute().empty())) { + + _error ("UserAgent: Set Service-Route with %s", account->getServiceRoute().c_str()); + + pjsip_route_hdr *route_set = pjsip_route_hdr_create (_pool); + pjsip_route_hdr *routing = pjsip_route_hdr_create (_pool); + pjsip_sip_uri *url = pjsip_sip_uri_create (_pool, 0); + routing->name_addr.uri = (pjsip_uri*) url; + pj_strdup2 (_pool, &url->host, account->getServiceRoute().c_str()); + + pj_list_push_back (&route_set, pjsip_hdr_clone (_pool, routing)); + + pjsip_dlg_set_route_set (dialog, route_set); + } + // Set the appropriate transport pjsip_tpselector *tp; @@ -2405,7 +2435,7 @@ int SIPVoIPLink::createUdpTransport (AccountID id) pjsip_host_port a_name; // char tmpIP[32]; pjsip_transport *transport; - std::string listeningAddress = "127.0.0.1"; + std::string listeningAddress = "0.0.0.0"; int listeningPort = _regPort; /* Use my local address as default value */ @@ -2450,6 +2480,7 @@ int SIPVoIPLink::createUdpTransport (AccountID id) // Init bound address to ANY bound_addr.sin_addr.s_addr = pj_htonl (PJ_INADDR_ANY); + loadSIPLocalIP (&listeningAddress); } else { // bind this account to a specific interface @@ -2463,16 +2494,22 @@ int SIPVoIPLink::createUdpTransport (AccountID id) // Create UDP-Server (default port: 5060) // Use here either the local information or the published address - if (account != NULL && !account->getPublishedSameasLocal ()) { + if (account && !account->getPublishedSameasLocal ()) { // Set the listening address to the published address listeningAddress = account->getPublishedAddress (); + // Set the listening port to the published port listeningPort = account->getPublishedPort (); _debug ("UserAgent: Creating UDP transport published %s:%i", listeningAddress.c_str (), listeningPort); } + // We must specify this here to avoid the IP2IP_PROFILE + // to create a transport with name 0.0.0.0 to appear in the via header + if (id == IP2IP_PROFILE) + loadSIPLocalIP (&listeningAddress); + if (listeningAddress == "" || listeningPort == 0) { _error ("UserAgent: Error invalid address for new udp transport"); return !PJ_SUCCESS; @@ -2598,9 +2635,13 @@ std::string SIPVoIPLink::findLocalAddressFromUri (const std::string& uri, pjsip_ } std::string localaddr (localAddress.ptr, localAddress.slen); + + if (localaddr == "0.0.0.0") + loadSIPLocalIP (&localaddr); + _debug ("SIP: Local address discovered from attached transport: %s", localaddr.c_str()); - return std::string (localAddress.ptr, localAddress.slen); + return localaddr; } @@ -3019,27 +3060,9 @@ void set_voicemail_info (AccountID account, pjsip_msg_body *body) Manager::instance().startVoiceMessageNotification (account, voicemail); } -void SIPVoIPLink::handle_reinvite (SIPCall *call) +void SIPVoIPLink::handle_reinvite (SIPCall *call UNUSED) { - _debug ("UserAgent: Handle reinvite"); - /* - // Close the previous RTP session - call->getAudioRtp()->stop (); - call->setAudioStart (false); - - _debug ("Create new rtp session from handle_reinvite : %s:%i", call->getLocalIp().c_str(), call->getLocalAudioPort()); - _debug ("UserAgent: handle_reinvite"); - - try { - call->getAudioRtp()->initAudioRtpSession (call); - } catch (...) { - _debug ("! SIP Failure: Unable to create RTP Session (%s:%d)", __FILE__, __LINE__); - } - - - _debug("Handle reINVITE"); - */ } // This callback is called when the invite session state has changed @@ -3057,8 +3080,6 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e) _error ("UserAgent: Error: Call is NULL in call state changed callback"); return; } else { - // _debug(" call_on_state_changed: call id %s", call->getCallId().c_str()); - // _debug(" call_on_state_changed: call state %s", invitationStateMap[call->getInvSession()->state]); } //Retrieve the body message @@ -3326,8 +3347,9 @@ void call_on_media_update (pjsip_inv_session *inv, pj_status_t status) // if RTPFALLBACK, change RTP session AccountID accountID = Manager::instance().getAccountFromCall (call->getCallId()); + SIPAccount *account = (SIPAccount *) Manager::instance().getAccount (accountID); - if (Manager::instance().getConfigString (accountID, SRTP_RTP_FALLBACK) == "true") + if (account->getSrtpFallback()) call->getAudioRtp()->initAudioRtpSession (call); } @@ -3365,11 +3387,11 @@ void call_on_media_update (pjsip_inv_session *inv, pj_status_t status) } -void call_on_forked (pjsip_inv_session *inv, pjsip_event *e) +void call_on_forked (pjsip_inv_session *inv UNUSED, pjsip_event *e UNUSED) { } -void call_on_tsx_changed (pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e) +void call_on_tsx_changed (pjsip_inv_session *inv UNUSED, pjsip_transaction *tsx, pjsip_event *e) { assert (tsx); @@ -3407,7 +3429,9 @@ void call_on_tsx_changed (pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_ } // Must reply 200 OK on SIP INFO request else if (request.find (method_info) != (size_t)-1) { + pjsip_dlg_create_response (inv->dlg, r_data, PJSIP_SC_OK, NULL, &t_data); + pjsip_dlg_send_response (inv->dlg, tsx, t_data); } } @@ -3467,7 +3491,11 @@ void regc_cb (struct pjsip_regc_cbparam *param) //_debug("Received client registration callback wiht code: %i, %s\n", param->code, descriptionprint.c_str()); DBusManager::instance().getCallManager()->registrationStateChanged (account->getAccountID(), std::string (description->ptr, description->slen), param->code); std::pair<int, std::string> details (param->code, std::string (description->ptr, description->slen)); - account->setRegistrationStateDetailed (details); + + + // there a race condition for this ressource when closing the application + if (account) + account->setRegistrationStateDetailed (details); } if (param->status == PJ_SUCCESS) { @@ -3504,7 +3532,7 @@ void regc_cb (struct pjsip_regc_cbparam *param) out << (expire_value * 2); std::string s = out.str(); - Manager::instance().setConfig (account->getAccountID(), CONFIG_ACCOUNT_REGISTRATION_EXPIRE, s); + account->setRegistrationExpire (s); account->registerVoIPLink(); } break; @@ -3718,18 +3746,19 @@ mod_on_rx_request (pjsip_rx_data *rdata) /******************************************* URL HOOK *********************************************/ - if (Manager::instance().getConfigString (HOOKS, URLHOOK_SIP_ENABLED) == "1") { + if (Manager::instance().hookPreference.getSipEnabled()) { _debug ("UserAgent: Set sip url hooks"); std::string header_value; - header_value = fetch_header_value (rdata->msg_info.msg, Manager::instance().getConfigString (HOOKS, URLHOOK_SIP_FIELD)); + header_value = fetch_header_value (rdata->msg_info.msg, + Manager::instance().hookPreference.getUrlSipField()); if (header_value.size () < header_value.max_size()) { if (header_value!="") { urlhook->addAction (header_value, - Manager::instance().getConfigString (HOOKS, URLHOOK_COMMAND)); + Manager::instance().hookPreference.getUrlCommand()); } } else throw length_error ("UserAgent: Url exceeds std::string max_size"); @@ -4304,7 +4333,7 @@ void xfer_svr_cb (pjsip_evsub *sub, pjsip_event *event) } } -void on_rx_offer (pjsip_inv_session *inv, const pjmedia_sdp_session *offer) +void on_rx_offer (pjsip_inv_session *inv, const pjmedia_sdp_session *offer UNUSED) { _info ("UserAgent: Received SDP offer"); @@ -4582,7 +4611,7 @@ std::vector<std::string> SIPVoIPLink::getAllIpInterfaceByName (void) } -pj_bool_t stun_sock_on_status (pj_stun_sock *stun_sock, pj_stun_sock_op op, pj_status_t status) +pj_bool_t stun_sock_on_status (pj_stun_sock *stun_sock UNUSED, pj_stun_sock_op op UNUSED, pj_status_t status) { if (status == PJ_SUCCESS) return PJ_TRUE; @@ -4590,7 +4619,7 @@ pj_bool_t stun_sock_on_status (pj_stun_sock *stun_sock, pj_stun_sock_op op, pj_s return PJ_FALSE; } -pj_bool_t stun_sock_on_rx_data (pj_stun_sock *stun_sock, void *pkt, unsigned pkt_len, const pj_sockaddr_t *src_addr, unsigned addr_len) +pj_bool_t stun_sock_on_rx_data (pj_stun_sock *stun_sock UNUSED, void *pkt UNUSED, unsigned pkt_len UNUSED, const pj_sockaddr_t *src_addr UNUSED, unsigned addr_len UNUSED) { return PJ_TRUE; } diff --git a/sflphone-common/src/sip/sipvoiplink.h b/sflphone-common/src/sip/sipvoiplink.h index f88f818cc2ded3c8a54d5c53cdf5df5161b6046c..e90db00a80e1e08f699300169beac0b40c9b0825 100644 --- a/sflphone-common/src/sip/sipvoiplink.h +++ b/sflphone-common/src/sip/sipvoiplink.h @@ -71,443 +71,445 @@ class SIPCall; class SIPVoIPLink : public VoIPLink { - public: - - /** - * Singleton method. Enable to retrieve the unique static instance - * @return SIPVoIPLink* A pointer on the object - */ - static SIPVoIPLink* instance( const AccountID& id ); - - /** - * Destructor - */ - ~SIPVoIPLink(); - - /* Copy Constructor */ - SIPVoIPLink(const SIPVoIPLink& rh); - - /* Assignment Operator */ - SIPVoIPLink& operator=( const SIPVoIPLink& rh); - - /** - * Try to initiate the pjsip engine/thread and set config - * @return bool True if OK - */ - bool init(void); - - /** - * Shut the library and clean up - */ - void terminate( void ); - - /** - * Event listener. Each event send by the call manager is received and handled from here - */ - void getEvent(void); - - /** - * Build and send SIP registration request - * @return bool True on success - * false otherwise - */ - int sendRegister(AccountID id); - - /** - * Build and send SIP unregistration request - * @return bool True on success - * false otherwise - */ - int sendUnregister(AccountID id); - - /** - * Place a new call - * @param id The call identifier - * @param toUrl The Sip address of the recipient of the call - * @return Call* The current call - */ - Call* newOutgoingCall(const CallID& id, const std::string& toUrl); - - /** - * Answer the call - * @param id The call identifier - * @return int True on success - */ - bool answer(const CallID& id); - - /** - * Hang up the call - * @param id The call identifier - * @return bool True on success - */ - bool hangup(const CallID& id); - - /** - * Hang up the call - * @param id The call identifier - * @return bool True on success - */ - bool peerHungup(const CallID& id); - - /** - * Cancel the call - * @param id The call identifier - * @return bool True on success - */ - bool cancel(const CallID& id); - - /** - * Put the call on hold - * @param id The call identifier - * @return bool True on success - */ - bool onhold(const CallID& id); - - /** - * Put the call off hold - * @param id The call identifier - * @return bool True on success - */ - bool offhold(const CallID& id); - - /** - * Transfer the call - * @param id The call identifier - * @param to The recipient of the transfer - * @return bool True on success - */ - bool transfer(const CallID& id, const std::string& to); - - /** Handle the incoming refer msg, not finished yet */ - bool transferStep2(SIPCall* call); - - /** - * Refuse the call - * @param id The call identifier - * @return bool True on success - */ - bool refuse (const CallID& id); - - /** - * Send DTMF refering to account configuration - * @param id The call identifier - * @param code The char code - * @return bool True on success - */ - bool carryingDTMFdigits(const CallID& id, char code); - - /** - * Send Dtmf using SIP INFO message - */ - bool dtmfSipInfo(SIPCall *call, char code); - - /** - * Send Dtmf over RTP - */ - bool dtmfOverRtp(SIPCall* call, char code); - - /** - * Terminate every call not hangup | brutal | Protected by mutex - */ - void terminateSIPCall(); - - /** - * Terminate only one call - */ - void terminateOneCall(const CallID& id); - - /** - * Send an outgoing call invite - * @param call The current call - * @return bool True if all is correct - */ - bool SIPOutgoingInvite(SIPCall* call); - - /** - * Start a SIP Call - * @param call The current call - * @param subject Undocumented - * @return true if all is correct - */ - bool SIPStartCall(SIPCall* call, const std::string& subject); - - /** - * Tell the user that the call was answered - * @param - */ - void SIPCallAnswered(SIPCall *call, pjsip_rx_data *rdata); - - /** - * Handling 5XX/6XX error - * @param - */ - void SIPCallServerFailure(SIPCall *call); - - /** - * Peer close the connection - * @param - */ - void SIPCallClosed(SIPCall *call); - - /** - * The call pointer was released - * If the call was not cleared before, report an error - * @param - */ - void SIPCallReleased(SIPCall *call); - - /** - * Handle a re-invite request by the remote peer. - * A re-invite is an invite request inside a dialog. - * When receiving a re-invite, we close the current rtp session and create a new one with the updated information - */ - void handle_reinvite (SIPCall *call); - - /** - * SIPCall accessor - * @param id The call identifier - * @return SIPCall* A pointer on SIPCall object - */ - SIPCall* getSIPCall(const CallID& id); - - /** when we init the listener, how many times we try to bind a port? */ - int _nbTryListenAddr; - - /** Increment the number of SIP account connected to this link */ - void incrementClients (void) { _clients++; } - - /** Decrement the number of SIP account connected to this link */ - void decrementClients (void); - - /** - * Set Recording - * @param id The call identifier - */ - void setRecording(const CallID& id); - - /** - * Returning state (true recording) - * @param id The call identifier - */ - bool isRecording(const CallID& id); - - /** - * Return the codec protocol used for this call - * @param id The call identifier - */ - std::string getCurrentCodecName(); - - int inv_session_reinvite (SIPCall *call, std::string direction=""); - - bool new_ip_to_ip_call (const CallID& id, const std::string& to); - - std::string get_useragent_name (const AccountID& id); - - /** - * List all the interfaces on the system and return - * a vector list containing their IPV4 address. - * @param void - * @return std::vector<std::string> A std::string vector - * of IPV4 address available on all of the interfaces on - * the system. - */ - std::vector<std::string> getAllIpInterface(void); - - - /** - * List all the interfaces on the system and return - * a vector list containing their name (eth0, eth0:1 ...). - * @param void - * @return std::vector<std::string> A std::string vector - * of interface name available on all of the interfaces on - * the system. - */ - std::vector<std::string> getAllIpInterfaceByName(void); - - - /** - * List all the interfaces on the system and return - * a vector list containing their name (eth0, eth0:1 ...). - * @param void - * @return std::vector<std::string> A std::string vector - * of interface name available on all of the interfaces on - * the system. - */ - std::string getInterfaceAddrFromName(std::string ifaceName); - - - /** - * Initialize the transport selector - * @param transport A transport associated with an account - * @param tp_sel A pointer to receive the transport selector structure - * - * @return pj_status_t PJ_SUCCESS if the structure was successfully initialized - */ - pj_status_t init_transport_selector (pjsip_transport *transport, pjsip_tpselector **tp_sel); - - /** - * Requests PJSIP library for local IP address, using pj_gethostbyname() - * @param addr* A string to be initialized - * - * @return bool True if addr successfully initialized - */ - bool loadSIPLocalIP (std::string *addr); - - - /** - * This function unset the transport for a given account. It tests wether the - * associated transport is used by other accounts. If not, it shutdown the transport - * putting its reference counter to zero. PJSIP assumes transport destruction since - * this action can be delayed by ongoing SIP transactions. - */ - void shutdownSipTransport(const AccountID& accountID); - - bool sendTextMessage (const std::string& callID, const std::string& message); - - private: - /** - * Constructor - * @param accountID The account identifier - */ - SIPVoIPLink(const AccountID& accountID); - - /* The singleton instance */ - static SIPVoIPLink* _instance; - - /** - * Enable the SIP SRV resolver - * @param endpt The SIP endpoint - * @param p_resv Pointer to receive The DNS resolver instance - * - * @return pj_status_t PJ_SUCCESS on success - */ - pj_status_t enable_dns_srv_resolver (pjsip_endpoint *endpt, pj_dns_resolver ** p_resv); - - void busy_sleep(unsigned msec); - - /** - * Initialize the PJSIP library - * Must be called before any other calls to the SIP layer - * - * @return bool True on success - */ - bool pjsip_init(); - - /** - * Delete link-related stuff like calls - */ - bool pjsip_shutdown(void); - - pj_status_t stunServerResolve (AccountID id); - - - /** - * Function used to create a new sip transport or get an existing one from the map. - * The SIP transport is "acquired" according to account's current settings. - * This function should be called before registering an account - * @param accountID An account id for which transport is to be set - * - * @return bool True if the account is successfully created or successfully obtained - * from the transport map - */ - bool acquireTransport(const AccountID& accountID); - - - /** - * Create the default UDP transport according ot Ip2Ip profile settings - */ - bool createDefaultSipUdpTransport(); - - - /** - * Create the default TLS litener using IP2IP_PROFILE settings - */ - void createDefaultSipTlsListener(); - - - /** - * Create the default TLS litener according to account settings. - */ - void createTlsListener(const AccountID& accountID); - - - /** - * General Sip transport creation method according to the - * transport type specified in account settings - * @param id The account id for which a transport must - * be created. - */ - bool createSipTransport(AccountID id); - - - /** - * Method to store newly created UDP transport in internal transport map. - * Transports are stored in order to retreive them in case - * several accounts would share the same port number for UDP transprt. - * @param key The transport's port number - * @param transport A pointer to the UDP transport - */ - bool addTransportToMap(std::string key, pjsip_transport* transport); - - /** - * Create SIP UDP transport from account's setting - * @param id The account id for which a transport must - * be created. - * @return pj_status_t PJ_SUCCESS on success - */ - int createUdpTransport (AccountID = ""); - - /** - * Create a TLS transport from the default TLS listener from - * @param id The account id for which a transport must - * be created. - * @return pj_status_t PJ_SUCCESS on success - */ - pj_status_t createTlsTransport(const AccountID& id, std::string remoteAddr); - - /** - * Create a UDP transport using stun server to resove public address - * @param id The account id for which a transport must - * be created. - * @return pj_status_t PJ_SUCCESS on success - */ - pj_status_t createAlternateUdpTransport (AccountID id); - - - /** - * UDP Transports are stored in this map in order to retreive them in case - * several accounts would share the same port number. - */ - SipTransportMap _transportMap; - - /** For registration use only */ - int _regPort; - - /** Threading object */ - EventThread* _evThread; - ost::Mutex _mutexSIP; - - /* Number of SIP accounts connected to the link */ - int _clients; - - /* - * Get the correct address to use (ie advertised) from - * a uri. The corresponding transport that should be used - * with that uri will be discovered. - * - * @param uri The uri from which we want to discover the address to use - * @param transport The transport to use to discover the address - * @return pj_str_t The extern (public) address - */ - std::string findLocalAddressFromUri(const std::string& uri, pjsip_transport *transport); - - /* - * Does the same as findLocalAddressFromUri but returns a port. - * @param uri The uri from which we want to discover the port to use - * @param transport The transport to use to discover the port - * @return int The extern (public) port - */ - int findLocalPortFromUri(const std::string& uri, pjsip_transport *transport); + public: + + /** + * Singleton method. Enable to retrieve the unique static instance + * @return SIPVoIPLink* A pointer on the object + */ + static SIPVoIPLink* instance (const AccountID& id); + + /** + * Destructor + */ + ~SIPVoIPLink(); + + /* Copy Constructor */ + SIPVoIPLink (const SIPVoIPLink& rh); + + /* Assignment Operator */ + SIPVoIPLink& operator= (const SIPVoIPLink& rh); + + /** + * Try to initiate the pjsip engine/thread and set config + * @return bool True if OK + */ + bool init (void); + + /** + * Shut the library and clean up + */ + void terminate (void); + + /** + * Event listener. Each event send by the call manager is received and handled from here + */ + void getEvent (void); + + /** + * Build and send SIP registration request + * @return bool True on success + * false otherwise + */ + int sendRegister (AccountID id); + + /** + * Build and send SIP unregistration request + * @return bool True on success + * false otherwise + */ + int sendUnregister (AccountID id); + + /** + * Place a new call + * @param id The call identifier + * @param toUrl The Sip address of the recipient of the call + * @return Call* The current call + */ + Call* newOutgoingCall (const CallID& id, const std::string& toUrl); + + /** + * Answer the call + * @param id The call identifier + * @return int True on success + */ + bool answer (const CallID& id); + + /** + * Hang up the call + * @param id The call identifier + * @return bool True on success + */ + bool hangup (const CallID& id); + + /** + * Hang up the call + * @param id The call identifier + * @return bool True on success + */ + bool peerHungup (const CallID& id); + + /** + * Cancel the call + * @param id The call identifier + * @return bool True on success + */ + bool cancel (const CallID& id); + + /** + * Put the call on hold + * @param id The call identifier + * @return bool True on success + */ + bool onhold (const CallID& id); + + /** + * Put the call off hold + * @param id The call identifier + * @return bool True on success + */ + bool offhold (const CallID& id); + + /** + * Transfer the call + * @param id The call identifier + * @param to The recipient of the transfer + * @return bool True on success + */ + bool transfer (const CallID& id, const std::string& to); + + /** Handle the incoming refer msg, not finished yet */ + bool transferStep2 (SIPCall* call); + + /** + * Refuse the call + * @param id The call identifier + * @return bool True on success + */ + bool refuse (const CallID& id); + + /** + * Send DTMF refering to account configuration + * @param id The call identifier + * @param code The char code + * @return bool True on success + */ + bool carryingDTMFdigits (const CallID& id, char code); + + /** + * Send Dtmf using SIP INFO message + */ + bool dtmfSipInfo (SIPCall *call, char code); + + /** + * Send Dtmf over RTP + */ + bool dtmfOverRtp (SIPCall* call, char code); + + /** + * Terminate every call not hangup | brutal | Protected by mutex + */ + void terminateSIPCall(); + + /** + * Terminate only one call + */ + void terminateOneCall (const CallID& id); + + /** + * Send an outgoing call invite + * @param call The current call + * @return bool True if all is correct + */ + bool SIPOutgoingInvite (SIPCall* call); + + /** + * Start a SIP Call + * @param call The current call + * @param subject Undocumented + * @return true if all is correct + */ + bool SIPStartCall (SIPCall* call, const std::string& subject); + + /** + * Tell the user that the call was answered + * @param + */ + void SIPCallAnswered (SIPCall *call, pjsip_rx_data *rdata); + + /** + * Handling 5XX/6XX error + * @param + */ + void SIPCallServerFailure (SIPCall *call); + + /** + * Peer close the connection + * @param + */ + void SIPCallClosed (SIPCall *call); + + /** + * The call pointer was released + * If the call was not cleared before, report an error + * @param + */ + void SIPCallReleased (SIPCall *call); + + /** + * Handle a re-invite request by the remote peer. + * A re-invite is an invite request inside a dialog. + * When receiving a re-invite, we close the current rtp session and create a new one with the updated information + */ + void handle_reinvite (SIPCall *call); + + /** + * SIPCall accessor + * @param id The call identifier + * @return SIPCall* A pointer on SIPCall object + */ + SIPCall* getSIPCall (const CallID& id); + + /** when we init the listener, how many times we try to bind a port? */ + int _nbTryListenAddr; + + /** Increment the number of SIP account connected to this link */ + void incrementClients (void) { + _clients++; + } + + /** Decrement the number of SIP account connected to this link */ + void decrementClients (void); + + /** + * Set Recording + * @param id The call identifier + */ + void setRecording (const CallID& id); + + /** + * Returning state (true recording) + * @param id The call identifier + */ + bool isRecording (const CallID& id); + + /** + * Return the codec protocol used for this call + * @param id The call identifier + */ + std::string getCurrentCodecName(); + + int inv_session_reinvite (SIPCall *call, std::string direction=""); + + bool new_ip_to_ip_call (const CallID& id, const std::string& to); + + std::string get_useragent_name (const AccountID& id); + + /** + * List all the interfaces on the system and return + * a vector list containing their IPV4 address. + * @param void + * @return std::vector<std::string> A std::string vector + * of IPV4 address available on all of the interfaces on + * the system. + */ + std::vector<std::string> getAllIpInterface (void); + + + /** + * List all the interfaces on the system and return + * a vector list containing their name (eth0, eth0:1 ...). + * @param void + * @return std::vector<std::string> A std::string vector + * of interface name available on all of the interfaces on + * the system. + */ + std::vector<std::string> getAllIpInterfaceByName (void); + + + /** + * List all the interfaces on the system and return + * a vector list containing their name (eth0, eth0:1 ...). + * @param void + * @return std::vector<std::string> A std::string vector + * of interface name available on all of the interfaces on + * the system. + */ + std::string getInterfaceAddrFromName (std::string ifaceName); + + + /** + * Initialize the transport selector + * @param transport A transport associated with an account + * @param tp_sel A pointer to receive the transport selector structure + * + * @return pj_status_t PJ_SUCCESS if the structure was successfully initialized + */ + pj_status_t init_transport_selector (pjsip_transport *transport, pjsip_tpselector **tp_sel); + + /** + * Requests PJSIP library for local IP address, using pj_gethostbyname() + * @param addr* A string to be initialized + * + * @return bool True if addr successfully initialized + */ + bool loadSIPLocalIP (std::string *addr); + + + /** + * This function unset the transport for a given account. It tests wether the + * associated transport is used by other accounts. If not, it shutdown the transport + * putting its reference counter to zero. PJSIP assumes transport destruction since + * this action can be delayed by ongoing SIP transactions. + */ + void shutdownSipTransport (const AccountID& accountID); + + bool sendTextMessage (const std::string& callID, const std::string& message); + + private: + /** + * Constructor + * @param accountID The account identifier + */ + SIPVoIPLink (const AccountID& accountID); + + /* The singleton instance */ + static SIPVoIPLink* _instance; + + /** + * Enable the SIP SRV resolver + * @param endpt The SIP endpoint + * @param p_resv Pointer to receive The DNS resolver instance + * + * @return pj_status_t PJ_SUCCESS on success + */ + pj_status_t enable_dns_srv_resolver (pjsip_endpoint *endpt, pj_dns_resolver ** p_resv); + + void busy_sleep (unsigned msec); + + /** + * Initialize the PJSIP library + * Must be called before any other calls to the SIP layer + * + * @return bool True on success + */ + bool pjsip_init(); + + /** + * Delete link-related stuff like calls + */ + bool pjsip_shutdown (void); + + pj_status_t stunServerResolve (AccountID id); + + + /** + * Function used to create a new sip transport or get an existing one from the map. + * The SIP transport is "acquired" according to account's current settings. + * This function should be called before registering an account + * @param accountID An account id for which transport is to be set + * + * @return bool True if the account is successfully created or successfully obtained + * from the transport map + */ + bool acquireTransport (const AccountID& accountID); + + + /** + * Create the default UDP transport according ot Ip2Ip profile settings + */ + bool createDefaultSipUdpTransport(); + + + /** + * Create the default TLS litener using IP2IP_PROFILE settings + */ + void createDefaultSipTlsListener(); + + + /** + * Create the default TLS litener according to account settings. + */ + void createTlsListener (const AccountID& accountID); + + + /** + * General Sip transport creation method according to the + * transport type specified in account settings + * @param id The account id for which a transport must + * be created. + */ + bool createSipTransport (AccountID id); + + + /** + * Method to store newly created UDP transport in internal transport map. + * Transports are stored in order to retreive them in case + * several accounts would share the same port number for UDP transprt. + * @param key The transport's port number + * @param transport A pointer to the UDP transport + */ + bool addTransportToMap (std::string key, pjsip_transport* transport); + + /** + * Create SIP UDP transport from account's setting + * @param id The account id for which a transport must + * be created. + * @return pj_status_t PJ_SUCCESS on success + */ + int createUdpTransport (AccountID = ""); + + /** + * Create a TLS transport from the default TLS listener from + * @param id The account id for which a transport must + * be created. + * @return pj_status_t PJ_SUCCESS on success + */ + pj_status_t createTlsTransport (const AccountID& id, std::string remoteAddr); + + /** + * Create a UDP transport using stun server to resove public address + * @param id The account id for which a transport must + * be created. + * @return pj_status_t PJ_SUCCESS on success + */ + pj_status_t createAlternateUdpTransport (AccountID id); + + + /** + * UDP Transports are stored in this map in order to retreive them in case + * several accounts would share the same port number. + */ + SipTransportMap _transportMap; + + /** For registration use only */ + int _regPort; + + /** Threading object */ + EventThread* _evThread; + ost::Mutex _mutexSIP; + + /* Number of SIP accounts connected to the link */ + int _clients; + + /* + * Get the correct address to use (ie advertised) from + * a uri. The corresponding transport that should be used + * with that uri will be discovered. + * + * @param uri The uri from which we want to discover the address to use + * @param transport The transport to use to discover the address + * @return pj_str_t The extern (public) address + */ + std::string findLocalAddressFromUri (const std::string& uri, pjsip_transport *transport); + + /* + * Does the same as findLocalAddressFromUri but returns a port. + * @param uri The uri from which we want to discover the port to use + * @param transport The transport to use to discover the port + * @return int The extern (public) port + */ + int findLocalPortFromUri (const std::string& uri, pjsip_transport *transport); }; diff --git a/sflphone-common/src/user_cfg.h b/sflphone-common/src/user_cfg.h index 910e3f9e15691e625918a4eab7920034ca078ca7..980881f889bbfa09f2ed8d2b4a7d77df59d4c486 100644 --- a/sflphone-common/src/user_cfg.h +++ b/sflphone-common/src/user_cfg.h @@ -81,10 +81,9 @@ #define WINDOW_POSITION_Y "Window.positionY" #define SHOW_STATUSICON "Statusicon.show" - -#define IP2IP_PROFILE "IP2IP" +#define IP2IP_PROFILE "IP2IP" #define SIGNALISATION "VoIPLink" /** Section Signalisation */ -#define ZRTP_ZIDFILE "ZRTP.zidFile" /** The filename used for storing ZIDs */ +#define ZRTP_ZIDFILE "zidFile" /** The filename used for storing ZIDs */ #define PLAY_DTMF "DTMF.playDtmf" /** Whether or not should play dtmf */ #define PLAY_TONES "DTMF.playTones" /** Whether or not should play tones */ #define PULSE_LENGTH "DTMF.pulseLength" /** Length of the DTMF in millisecond */ @@ -105,11 +104,11 @@ #define URLHOOK_COMMAND "Hooks.url_command" #define URLHOOK_SIP_ENABLED "Hooks.sip_enabled" #define URLHOOK_IAX2_ENABLED "Hooks.iax2_enabled" -#define PHONE_NUMBER_HOOK_ENABLED "Hooks.phone_number_enabled" +#define PHONE_NUMBER_HOOK_ENABLED "Hooks.phone_number_enabled" #define PHONE_NUMBER_HOOK_ADD_PREFIX "Hooks.phone_number_add_prefix" #define EMPTY_FIELD "" /** Default value for empty field */ -#define DEFAULT_ACCOUNT_TYPE "SIP" +#define DEFAULT_ACCOUNT_TYPE "SIP" #define DFT_STUN_SERVER "stun.sflphone.org" /** Default STUN server address */ #define TRUE_STR "true" /** Default YES value */ #define FALSE_STR "false" /** Default NO value */ diff --git a/sflphone-common/src/voiplink.h b/sflphone-common/src/voiplink.h index e0d9bd6bdfc0de4f7ce4e780869479ba7736e8ff..f4bcecc2b7646da29cb8f8cc01d60a608c8d3efb 100644 --- a/sflphone-common/src/voiplink.h +++ b/sflphone-common/src/voiplink.h @@ -49,13 +49,14 @@ typedef std::map<CallID, Call*> CallMap; * @file voiplink.h * @brief Listener and manager interface for each VoIP protocol */ -class VoIPLink { +class VoIPLink +{ public: /** * Constructor * @param accountID The account identifier */ - VoIPLink(const AccountID& accountID); + VoIPLink (const AccountID& accountID); /** * Virtual destructor @@ -69,9 +70,9 @@ class VoIPLink { */ virtual void getEvent (void) = 0; - /** + /** * Virtual method - * Try to initiate the communication layer and set config + * Try to initiate the communication layer and set config * @return bool True if OK */ virtual bool init (void) = 0; @@ -88,7 +89,7 @@ class VoIPLink { * @return bool True on success * false otherwise */ - virtual int sendRegister ( AccountID id ) = 0; + virtual int sendRegister (AccountID id) = 0; /** * Virtual method @@ -96,7 +97,7 @@ class VoIPLink { * @return bool True on success * false otherwise */ - virtual int sendUnregister ( AccountID id ) = 0; + virtual int sendUnregister (AccountID id) = 0; /** * Place a new call @@ -104,49 +105,49 @@ class VoIPLink { * @param toUrl The address of the recipient of the call * @return Call* The current call */ - virtual Call* newOutgoingCall(const CallID& id, const std::string& toUrl) = 0; + virtual Call* newOutgoingCall (const CallID& id, const std::string& toUrl) = 0; /** * Answer the call * @param id The call identifier * @return bool True on success */ - virtual bool answer(const CallID& id) = 0; + virtual bool answer (const CallID& id) = 0; /** * Hang up a call * @param id The call identifier * @return bool True on success */ - virtual bool hangup(const CallID& id) = 0; + virtual bool hangup (const CallID& id) = 0; - /** - * Peer Hung up a call - * @param id The call identifier - * @return bool True on success - */ - virtual bool peerHungup(const CallID& id) = 0; + /** + * Peer Hung up a call + * @param id The call identifier + * @return bool True on success + */ + virtual bool peerHungup (const CallID& id) = 0; /** * Cancel the call dialing * @param id The call identifier * @return bool True on success */ - virtual bool cancel(const CallID& id) = 0; + virtual bool cancel (const CallID& id) = 0; /** * Put a call on hold * @param id The call identifier * @return bool True on success */ - virtual bool onhold(const CallID& id) = 0; + virtual bool onhold (const CallID& id) = 0; /** * Resume a call from hold state * @param id The call identifier * @return bool True on success */ - virtual bool offhold(const CallID& id) = 0; + virtual bool offhold (const CallID& id) = 0; /** * Transfer a call to specified URI @@ -154,14 +155,14 @@ class VoIPLink { * @param to The recipient of the call * @return bool True on success */ - virtual bool transfer(const CallID& id, const std::string& to) = 0; + virtual bool transfer (const CallID& id, const std::string& to) = 0; /** * Refuse incoming call * @param id The call identifier * @return bool True on success */ - virtual bool refuse(const CallID& id) = 0; + virtual bool refuse (const CallID& id) = 0; /** * Send DTMF @@ -169,40 +170,44 @@ class VoIPLink { * @param code The char code * @return bool True on success */ - virtual bool carryingDTMFdigits(const CallID& id, char code) = 0; + virtual bool carryingDTMFdigits (const CallID& id, char code) = 0; - /** - * Set Recording - * @param id The call identifier - */ - // virtual void setRecording(const CallID& id) = 0; + /** + * Set Recording + * @param id The call identifier + */ + // virtual void setRecording(const CallID& id) = 0; /** - * Return recording state - * @param id The call identifier - */ - // virtual bool isRecording(const CallID& id) = 0; + * Return recording state + * @param id The call identifier + */ + // virtual bool isRecording(const CallID& id) = 0; /** - * Return the codec protocol used for this call + * Return the codec protocol used for this call * @param id The call identifier */ virtual std::string getCurrentCodecName() = 0; - bool initDone (void) { return _initDone; } - void initDone (bool state) { _initDone = state; } + bool initDone (void) { + return _initDone; + } + void initDone (bool state) { + _initDone = state; + } /** Add a call to the call map (protected by mutex) * @param call A call pointer with a unique pointer * @return bool True if the call was unique and added */ - bool addCall(Call* call); + bool addCall (Call* call); /** Remove a call from the call map (protected by mutex) * @param id A Call ID * @return bool True if the call was correctly removed */ - bool removeCall(const CallID& id); + bool removeCall (const CallID& id); /** * Remove all the call from the map @@ -213,21 +218,25 @@ class VoIPLink { /** * @return AccountID parent Account's ID */ - inline AccountID& getAccountID(void) { return _accountID; } + inline AccountID& getAccountID (void) { + return _accountID; + } - Account* getAccountPtr(void); + Account* getAccountPtr (void); /** * @param accountID The account identifier */ - inline void setAccountID( const AccountID& accountID) { _accountID = accountID; } + inline void setAccountID (const AccountID& accountID) { + _accountID = accountID; + } - /** + /** * Get the call pointer from the call map (protected by mutex) * @param id A Call ID * @return Call* Call pointer or 0 */ - Call* getCall(const CallID& id); + Call* getCall (const CallID& id); private: /** diff --git a/sflphone-common/test/Makefile.am b/sflphone-common/test/Makefile.am index 616dab24a0de76d573afd76561cfababe7c6e453..c1fb3a2fab62863d8411494aa46bf0bc517a74bc 100644 --- a/sflphone-common/test/Makefile.am +++ b/sflphone-common/test/Makefile.am @@ -43,5 +43,5 @@ LLIBS=$(CPPUNIT_LIBS) \ ../src/sflphoned-numbercleaner.o \ ../src/sflphoned-observer.o \ ../src/sflphoned-voiplink.o \ + ../src/sflphoned-preferences.o \ ../src/libsflphone.la - diff --git a/sflphone-common/test/audiolayertest.cpp b/sflphone-common/test/audiolayertest.cpp index 154b95cb32f4c90c9bb097cefb8117183dae7a25..b60afe8cd05c3ad1076dad06dc555ea9dd28f2db 100644 --- a/sflphone-common/test/audiolayertest.cpp +++ b/sflphone-common/test/audiolayertest.cpp @@ -42,11 +42,10 @@ void AudioLayerTest::testAudioLayerConfig() { _debug ("-------------------- AudioLayerTest::testAudioLayerConfig --------------------\n"); - int sampling_rate = Manager::instance().getConfigInt (AUDIO, - AUDIO_SAMPLE_RATE); - int frame_size = Manager::instance().getConfigInt (AUDIO, ALSA_FRAME_SIZE); + // int sampling_rate = Manager::instance().audioPreference.getSmplrate(); + // int frame_size = Manager::instance().audioPreference.getFramesize(); - int layer = Manager::instance().getAudioDriver()->getLayerType(); + // int layer = Manager::instance().getAudioDriver()->getLayerType(); // if (layer != ALSA) // Manager::instance().switchAudioManager(); @@ -96,12 +95,12 @@ void AudioLayerTest::testPulseConnect() std::string alsaPlugin; int numCardIn, numCardOut, numCardRing, sampleRate, frameSize; - alsaPlugin = manager->getConfigString (AUDIO, ALSA_PLUGIN); - numCardIn = manager->getConfigInt (AUDIO, ALSA_CARD_ID_IN); - numCardOut = manager->getConfigInt (AUDIO, ALSA_CARD_ID_OUT); - numCardRing = manager->getConfigInt (AUDIO, ALSA_CARD_ID_RING); - sampleRate = manager->getConfigInt (AUDIO, AUDIO_SAMPLE_RATE); - frameSize = manager->getConfigInt (AUDIO, ALSA_FRAME_SIZE); + alsaPlugin = manager->audioPreference.getPlugin(); + numCardIn = manager->audioPreference.getCardin(); + numCardOut = manager->audioPreference.getCardout(); + numCardRing = manager->audioPreference.getCardring(); + sampleRate = manager->audioPreference.getSmplrate(); + frameSize = manager->audioPreference.getFramesize(); CPPUNIT_ASSERT (_pulselayer->getPlaybackStream() == NULL); CPPUNIT_ASSERT (_pulselayer->getRecordStream() == NULL); diff --git a/sflphone-common/test/configurationtest.cpp b/sflphone-common/test/configurationtest.cpp index c54e01c6a5cfd667ddf950c098127eb098ba7ac1..e79fc1d07eefe62e2bc6230d9217ed2538f2fc60 100644 --- a/sflphone-common/test/configurationtest.cpp +++ b/sflphone-common/test/configurationtest.cpp @@ -41,42 +41,31 @@ void ConfigurationTest::testDefaultValueAudio() { _debug ("-------------------- ConfigurationTest::testDefaultValueAudio() --------------------\n"); - CPPUNIT_ASSERT (Manager::instance().getConfigString (AUDIO, ALSA_CARD_ID_IN) == ALSA_DFT_CARD); - CPPUNIT_ASSERT (Manager::instance().getConfigString (AUDIO, ALSA_CARD_ID_OUT) == ALSA_DFT_CARD); - CPPUNIT_ASSERT (Manager::instance().getConfigString (AUDIO, AUDIO_SAMPLE_RATE) == DFT_SAMPLE_RATE); - CPPUNIT_ASSERT (Manager::instance().getConfigString (AUDIO, ALSA_FRAME_SIZE) == DFT_FRAME_SIZE); - CPPUNIT_ASSERT (Manager::instance().getConfigString (AUDIO, ALSA_PLUGIN) == PCM_DEFAULT); - CPPUNIT_ASSERT (Manager::instance().getConfigString (AUDIO, VOLUME_SPKR) == DFT_VOL_SPKR_STR); - CPPUNIT_ASSERT (Manager::instance().getConfigString (AUDIO, VOLUME_MICRO) == DFT_VOL_MICRO_STR); + CPPUNIT_ASSERT (Manager::instance().audioPreference.getCardin() == 0); // ALSA_DFT_CARD); + CPPUNIT_ASSERT (Manager::instance().audioPreference.getCardout() == 0); // ALSA_DFT_CARD); + CPPUNIT_ASSERT (Manager::instance().audioPreference.getSmplrate() == 44100); // DFT_SAMPLE_RATE); + CPPUNIT_ASSERT (Manager::instance().audioPreference.getFramesize() == 20); // DFT_FRAME_SIZE); + CPPUNIT_ASSERT (Manager::instance().audioPreference.getPlugin() == PCM_DEFAULT); + CPPUNIT_ASSERT (Manager::instance().audioPreference.getVolumespkr() == 100); + CPPUNIT_ASSERT (Manager::instance().audioPreference.getVolumemic() == 100); } void ConfigurationTest::testDefaultValuePreferences() { _debug ("-------------------- ConfigurationTest::testDefaultValuePreferences --------------------\n"); - CPPUNIT_ASSERT (Manager::instance().getConfigString (PREFERENCES, ZONE_TONE) == DFT_ZONE); - CPPUNIT_ASSERT (Manager::instance().getConfigString (PREFERENCES, CONFIG_DIALPAD) == NO_STR); - CPPUNIT_ASSERT (Manager::instance().getConfigString (PREFERENCES, CONFIG_RINGTONE) == YES_STR); - CPPUNIT_ASSERT (Manager::instance().getConfigString (PREFERENCES, CONFIG_SEARCHBAR) == YES_STR); - CPPUNIT_ASSERT (Manager::instance().getConfigString (PREFERENCES, CONFIG_START) == NO_STR); - CPPUNIT_ASSERT (Manager::instance().getConfigString (PREFERENCES, CONFIG_POPUP) == NO_STR); - CPPUNIT_ASSERT (Manager::instance().getConfigString (PREFERENCES, CONFIG_NOTIFY) == YES_STR); - CPPUNIT_ASSERT (Manager::instance().getConfigString (PREFERENCES, CONFIG_MAIL_NOTIFY) == NO_STR); - CPPUNIT_ASSERT (Manager::instance().getConfigString (PREFERENCES, CONFIG_VOLUME) == NO_STR); - //CPPUNIT_ASSERT (Manager::instance().getConfigString (PREFERENCES, REGISTRATION_EXPIRE) == DFT_EXPIRE_VALUE); - //CPPUNIT_ASSERT (Manager::instance().getConfigString (PREFERENCES, CONFIG_AUDIO) == DFT_AUDIO_MANAGER); - + CPPUNIT_ASSERT (Manager::instance().preferences.getZoneToneChoice() == DFT_ZONE); } void ConfigurationTest::testDefaultValueSignalisation() { _debug ("-------------------- ConfigurationTest::testDefaultValueSignalisation --------------------\n"); - CPPUNIT_ASSERT (Manager::instance().getConfigString (SIGNALISATION , SYMMETRIC) == YES_STR); - CPPUNIT_ASSERT (Manager::instance().getConfigString (SIGNALISATION , PLAY_DTMF) == YES_STR); - CPPUNIT_ASSERT (Manager::instance().getConfigString (SIGNALISATION , PLAY_TONES) == YES_STR); - CPPUNIT_ASSERT (Manager::instance().getConfigString (SIGNALISATION , PULSE_LENGTH) == DFT_PULSE_LENGTH_STR); - CPPUNIT_ASSERT (Manager::instance().getConfigString (SIGNALISATION , SEND_DTMF_AS) == SIP_INFO_STR); + CPPUNIT_ASSERT (Manager::instance().voipPreferences.getSymmetricRtp() == true); + CPPUNIT_ASSERT (Manager::instance().voipPreferences.getPlayDtmf() == true); + CPPUNIT_ASSERT (Manager::instance().voipPreferences.getPlayTones() == true); + CPPUNIT_ASSERT (Manager::instance().voipPreferences.getPulseLength() == 250); + CPPUNIT_ASSERT (Manager::instance().voipPreferences.getSendDtmfAs() == 0); } void ConfigurationTest::testLoadSIPAccount() @@ -132,8 +121,8 @@ void ConfigurationTest::testInitVolume() Manager::instance().initVolume(); - CPPUNIT_ASSERT (Manager::instance().getConfigInt (AUDIO, VOLUME_SPKR) == Manager::instance().getSpkrVolume()); - CPPUNIT_ASSERT (Manager::instance().getConfigInt (AUDIO, VOLUME_MICRO) == Manager::instance().getMicVolume()); + CPPUNIT_ASSERT (Manager::instance().audioPreference.getVolumespkr() == Manager::instance().getSpkrVolume()); + CPPUNIT_ASSERT (Manager::instance().audioPreference.getVolumemic() == Manager::instance().getMicVolume()); } void ConfigurationTest::testInitAudioDriver() @@ -149,11 +138,150 @@ void ConfigurationTest::testInitAudioDriver() CPPUNIT_FAIL ("Error while loading audio layer"); // Check if it has been created with the right type - if (Manager::instance().getConfigInt (PREFERENCES, CONFIG_AUDIO) == ALSA) + if (Manager::instance().preferences.getAudioApi() == ALSA) CPPUNIT_ASSERT_EQUAL (Manager::instance().getAudioDriver()->getLayerType(), ALSA); - else if (Manager::instance().getConfigInt (PREFERENCES, CONFIG_AUDIO) - == PULSEAUDIO) + else if (Manager::instance().preferences.getAudioApi() == PULSEAUDIO) CPPUNIT_ASSERT_EQUAL (Manager::instance().getAudioDriver()->getLayerType(), PULSEAUDIO); else CPPUNIT_FAIL ("Wrong audio layer type"); } + + +void ConfigurationTest::testYamlParser() +{ + + Conf::YamlParser *parser; + + try { + + parser = new Conf::YamlParser ("ymlParser.yml"); + parser->serializeEvents(); + parser->composeEvents(); + parser->constructNativeData(); + + delete parser; + parser = NULL; + + } catch (Conf::YamlParserException &e) { + _error ("ConfigTree: %s", e.what()); + } + +} + +void ConfigurationTest::testYamlEmitter() +{ + Conf::YamlEmitter *emitter; + + Conf::MappingNode accountmap (NULL); + Conf::MappingNode credentialmap (NULL); + Conf::MappingNode srtpmap (NULL); + Conf::MappingNode zrtpmap (NULL); + Conf::MappingNode tlsmap (NULL); + + + Conf::ScalarNode id ("Account:1278432417"); + Conf::ScalarNode username ("181"); + Conf::ScalarNode password ("pass181"); + Conf::ScalarNode alias ("sfl-181"); + Conf::ScalarNode hostname ("192.168.50.3"); + Conf::ScalarNode enable ("true"); + Conf::ScalarNode type ("SIP"); + Conf::ScalarNode expire ("3600"); + Conf::ScalarNode interface ("default"); + Conf::ScalarNode port ("5060"); + Conf::ScalarNode mailbox ("97"); + Conf::ScalarNode publishAddr ("192.168.50.182"); + Conf::ScalarNode publishPort ("5060"); + Conf::ScalarNode sameasLocal ("true"); + Conf::ScalarNode resolveOnce ("false"); + Conf::ScalarNode codecs ("0/9/110/111/112/"); + Conf::ScalarNode stunServer ("stun.sflphone.org"); + Conf::ScalarNode stunEnabled ("false"); + Conf::ScalarNode displayName ("Alexandre Savard"); + Conf::ScalarNode dtmfType ("sipinfo"); + + Conf::ScalarNode count ("0"); + + Conf::ScalarNode srtpenabled ("false"); + Conf::ScalarNode keyExchange ("sdes"); + Conf::ScalarNode rtpFallback ("false"); + + Conf::ScalarNode displaySas ("false"); + Conf::ScalarNode displaySasOnce ("false"); + Conf::ScalarNode helloHashEnabled ("false"); + Conf::ScalarNode notSuppWarning ("false"); + + Conf::ScalarNode tlsport (""); + Conf::ScalarNode certificate (""); + Conf::ScalarNode calist (""); + Conf::ScalarNode ciphers (""); + Conf::ScalarNode tlsenabled ("false"); + Conf::ScalarNode tlsmethod ("TLSV1"); + Conf::ScalarNode timeout ("0"); + Conf::ScalarNode tlspassword (""); + Conf::ScalarNode privatekey (""); + Conf::ScalarNode requirecertif ("true"); + Conf::ScalarNode server (""); + Conf::ScalarNode verifyclient ("true"); + Conf::ScalarNode verifyserver ("true"); + + accountmap.setKeyValue (aliasKey, &alias); + accountmap.setKeyValue (typeKey, &type); + accountmap.setKeyValue (idKey, &id); + accountmap.setKeyValue (usernameKey, &username); + accountmap.setKeyValue (passwordKey, &password); + accountmap.setKeyValue (hostnameKey, &hostname); + accountmap.setKeyValue (accountEnableKey, &enable); + accountmap.setKeyValue (mailboxKey, &mailbox); + accountmap.setKeyValue (expireKey, &expire); + accountmap.setKeyValue (interfaceKey, &interface); + accountmap.setKeyValue (portKey, &port); + accountmap.setKeyValue (publishAddrKey, &publishAddr); + accountmap.setKeyValue (publishPortKey, &publishPort); + accountmap.setKeyValue (sameasLocalKey, &sameasLocal); + accountmap.setKeyValue (resolveOnceKey, &resolveOnce); + accountmap.setKeyValue (dtmfTypeKey, &dtmfType); + accountmap.setKeyValue (displayNameKey, &displayName); + + accountmap.setKeyValue (srtpKey, &srtpmap); + srtpmap.setKeyValue (srtpEnableKey, &srtpenabled); + srtpmap.setKeyValue (keyExchangeKey, &keyExchange); + srtpmap.setKeyValue (rtpFallbackKey, &rtpFallback); + + accountmap.setKeyValue (zrtpKey, &zrtpmap); + zrtpmap.setKeyValue (displaySasKey, &displaySas); + zrtpmap.setKeyValue (displaySasOnceKey, &displaySasOnce); + zrtpmap.setKeyValue (helloHashEnabledKey, &helloHashEnabled); + zrtpmap.setKeyValue (notSuppWarningKey, ¬SuppWarning); + + accountmap.setKeyValue (credKey, &credentialmap); + credentialmap.setKeyValue (credentialCountKey, &count); + + accountmap.setKeyValue (tlsKey, &tlsmap); + tlsmap.setKeyValue (tlsPortKey, &tlsport); + tlsmap.setKeyValue (certificateKey, &certificate); + tlsmap.setKeyValue (calistKey, &calist); + tlsmap.setKeyValue (ciphersKey, &ciphers); + tlsmap.setKeyValue (tlsEnableKey, &tlsenabled); + tlsmap.setKeyValue (methodKey, &tlsmethod); + tlsmap.setKeyValue (timeoutKey, &timeout); + tlsmap.setKeyValue (tlsPasswordKey, &tlspassword); + tlsmap.setKeyValue (privateKeyKey, &privatekey); + tlsmap.setKeyValue (requireCertifKey, &requirecertif); + tlsmap.setKeyValue (serverKey, &server); + tlsmap.setKeyValue (verifyClientKey, &verifyclient); + tlsmap.setKeyValue (verifyServerKey, &verifyserver); + + try { + emitter = new Conf::YamlEmitter ("/tmp/ymlEmiter.txt"); + + emitter->serializeAccount (&accountmap); + emitter->serializeAccount (&accountmap); + emitter->serializeData(); + + delete emitter; + } catch (Conf::YamlEmitterException &e) { + _error ("ConfigTree: %s", e.what()); + } + +} diff --git a/sflphone-common/test/configurationtest.h b/sflphone-common/test/configurationtest.h old mode 100644 new mode 100755 index 1e2f572aa55ecd36324eb1672f0954a6f7badb94..84d840674fad87fcaf467925c05a9537a7983464 --- a/sflphone-common/test/configurationtest.h +++ b/sflphone-common/test/configurationtest.h @@ -50,6 +50,11 @@ #include "audio/audiolayer.h" #include "global.h" #include "user_cfg.h" +#include "config/yamlparser.h" +#include "config/yamlemitter.h" +#include "config/yamlnode.h" +#include "sip/sipaccount.h" +#include "account.h" class ConfigurationTest: public CppUnit::TestFixture { @@ -57,11 +62,13 @@ class ConfigurationTest: public CppUnit::TestFixture { * Use cppunit library macros to add unit test the factory */ CPPUNIT_TEST_SUITE( ConfigurationTest ); - CPPUNIT_TEST( testInitVolume ); - CPPUNIT_TEST( testDefaultValueAudio ); - CPPUNIT_TEST( testDefaultValuePreferences ); - CPPUNIT_TEST( testDefaultValueSignalisation ); - CPPUNIT_TEST( testInitAudioDriver ); +// CPPUNIT_TEST( testInitVolume ); +// CPPUNIT_TEST( testDefaultValueAudio ); +// CPPUNIT_TEST( testDefaultValuePreferences ); +// CPPUNIT_TEST( testDefaultValueSignalisation ); +// CPPUNIT_TEST( testInitAudioDriver ); +// CPPUNIT_TEST( testYamlParser ); + CPPUNIT_TEST( testYamlEmitter ); CPPUNIT_TEST_SUITE_END(); public: @@ -91,6 +98,10 @@ public: void testInitVolume(); void testInitAudioDriver(); + + void testYamlParser(); + + void testYamlEmitter(); }; /* Register our test module */ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ConfigurationTest, "ConfigurationTest"); diff --git a/sflphone-common/test/constants.h b/sflphone-common/test/constants.h index 5b3d0884f4c042d3b91b90325bab1f6d5aefb6aa..9272bfd7a86ce880201978b55996e88edcecff86 100644 --- a/sflphone-common/test/constants.h +++ b/sflphone-common/test/constants.h @@ -33,9 +33,9 @@ #define YES_STR "1" #define NO_STR "0" -#define HISTORY_SAMPLE "history-sample" +#define HISTORY_SAMPLE "history-sample.tpl" #define HISTORY_SAMPLE_SIZE 3 -#define CONFIG_SAMPLE "sflphonedrc-sample" -#define HUGE_HISTORY_LIMIT 20000 +#define CONFIG_SAMPLE "sflphoned-sample.yml" +#define HUGE_HISTORY_LIMIT 999999999 #endif /* CONSTANTS_H_ */ diff --git a/sflphone-common/test/cppunitresults.xml b/sflphone-common/test/cppunitresults.xml new file mode 100644 index 0000000000000000000000000000000000000000..02abe4703dcf4d4d7290bca67f4f0feba3033c05 --- /dev/null +++ b/sflphone-common/test/cppunitresults.xml @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding='ISO-8859-1' standalone='yes' ?> +<TestRun> + <FailedTests></FailedTests> + <SuccessfulTests> + <Test id="1"> + <Name>AccountTest::TestAddRemove</Name> + </Test> + <Test id="2"> + <Name>AudioLayerTest::testAudioLayerConfig</Name> + </Test> + <Test id="3"> + <Name>AudioLayerTest::testPulseConnect</Name> + </Test> + <Test id="4"> + <Name>ConfigurationTest::testYamlEmitter</Name> + </Test> + <Test id="5"> + <Name>HistoryTest::test_create_history_path</Name> + </Test> + <Test id="6"> + <Name>HistoryTest::test_save_history_items_map</Name> + </Test> + <Test id="7"> + <Name>HistoryTest::test_load_history_from_file</Name> + </Test> + <Test id="8"> + <Name>HistoryTest::test_load_history_items_map</Name> + </Test> + <Test id="9"> + <Name>HistoryTest::test_get_history_serialized</Name> + </Test> + <Test id="10"> + <Name>HistoryTest::test_set_serialized_history</Name> + </Test> + <Test id="11"> + <Name>HistoryTest::test_set_serialized_history_with_limit</Name> + </Test> + <Test id="12"> + <Name>HistoryTest::test_save_history_to_file</Name> + </Test> + <Test id="13"> + <Name>HookManagerTest::testAddAction</Name> + </Test> + <Test id="14"> + <Name>HookManagerTest::testLargeUrl</Name> + </Test> + <Test id="15"> + <Name>NumberCleanerTest::test_format_1</Name> + </Test> + <Test id="16"> + <Name>NumberCleanerTest::test_format_2</Name> + </Test> + <Test id="17"> + <Name>NumberCleanerTest::test_format_3</Name> + </Test> + <Test id="18"> + <Name>NumberCleanerTest::test_format_4</Name> + </Test> + <Test id="19"> + <Name>NumberCleanerTest::test_format_5</Name> + </Test> + <Test id="20"> + <Name>NumberCleanerTest::test_format_6</Name> + </Test> + <Test id="21"> + <Name>NumberCleanerTest::test_format_10</Name> + </Test> + <Test id="22"> + <Name>PluginManagerTest::testLoadDynamicLibrary</Name> + </Test> + <Test id="23"> + <Name>PluginManagerTest::testUnloadDynamicLibrary</Name> + </Test> + <Test id="24"> + <Name>PluginManagerTest::testInstanciatePlugin</Name> + </Test> + <Test id="25"> + <Name>PluginManagerTest::testInitPlugin</Name> + </Test> + <Test id="26"> + <Name>PluginManagerTest::testRegisterPlugin</Name> + </Test> + <Test id="27"> + <Name>PluginManagerTest::testLoadPlugins</Name> + </Test> + <Test id="28"> + <Name>PluginManagerTest::testUnloadPlugins</Name> + </Test> + <Test id="29"> + <Name>RtpTest::testRtpInitClose</Name> + </Test> + <Test id="30"> + <Name>SdesNegotiatorTest::testTagPattern</Name> + </Test> + <Test id="31"> + <Name>SdesNegotiatorTest::testCryptoSuitePattern</Name> + </Test> + <Test id="32"> + <Name>SdesNegotiatorTest::testKeyParamsPattern</Name> + </Test> + <Test id="33"> + <Name>SdesNegotiatorTest::testKeyParamsPatternWithoutMKI</Name> + </Test> + <Test id="34"> + <Name>SdesNegotiatorTest::testNegotiation</Name> + </Test> + <Test id="35"> + <Name>SdesNegotiatorTest::testMostSimpleCase</Name> + </Test> + </SuccessfulTests> + <Statistics> + <Tests>35</Tests> + <FailuresTotal>0</FailuresTotal> + <Errors>0</Errors> + <Failures>0</Failures> + </Statistics> +</TestRun> diff --git a/sflphone-common/test/history-sample b/sflphone-common/test/history-sample deleted file mode 100644 index a6f39f4ed3316e02f1d5d3b750efc16ad43276d5..0000000000000000000000000000000000000000 --- a/sflphone-common/test/history-sample +++ /dev/null @@ -1,21 +0,0 @@ -[144562436] -accountid= -name=Savoir-faire Linux -number=514-276-5468 -timestamp_stop=144562458 -type=0 - -[747638685] -accountid=Account:1239059899 -name=Emmanuel Milou -number=136 -timestamp_stop=747638765 -type=2 - -[775354456] -accountid=Account:43789459478 -name= -number=5143848557 -timestamp_stop=775354987 -type=1 - diff --git a/sflphone-common/test/history-sample.tpl b/sflphone-common/test/history-sample.tpl index 221e449538f4d36e20f35bcb1c6d0dc1721e515e..a6f39f4ed3316e02f1d5d3b750efc16ad43276d5 100644 --- a/sflphone-common/test/history-sample.tpl +++ b/sflphone-common/test/history-sample.tpl @@ -1,20 +1,21 @@ [144562436] -number=514-276-5468 +accountid= name=Savoir-faire Linux -type=0 +number=514-276-5468 timestamp_stop=144562458 -accountid= +type=0 [747638685] +accountid=Account:1239059899 name=Emmanuel Milou -timestamp_stop=747638765 number=136 +timestamp_stop=747638765 type=2 -accountid=Account:1239059899 [775354456] -number=5143848557 +accountid=Account:43789459478 name= +number=5143848557 timestamp_stop=775354987 type=1 -accountid=Account:43789459478 + diff --git a/sflphone-common/test/historytest.cpp b/sflphone-common/test/historytest.cpp index f2fe88f4941d357ef1e8551f85f655b9ca977b8d..0aa8e630e91a6be0ae5316f2035b115187540f03 100644 --- a/sflphone-common/test/historytest.cpp +++ b/sflphone-common/test/historytest.cpp @@ -143,11 +143,9 @@ void HistoryTest::test_get_history_serialized() // Check the first tmp = "0|514-276-5468|Savoir-faire Linux|144562458|empty"; + std::cout << res ["144562436"] << std::endl; CPPUNIT_ASSERT (Validator::isEqual (tmp, res ["144562436"])); - tmp = "2|136|Emmanuel Milou|747638765|Account:1239059899"; - CPPUNIT_ASSERT (Validator::isEqual (tmp, res ["747638685"])); - // the account ID does not correspond to a loaded account tmp = "1|5143848557|empty|775354987|empty"; CPPUNIT_ASSERT (Validator::isEqual (tmp, res ["775354456"])); @@ -179,9 +177,6 @@ void HistoryTest::test_set_serialized_history() tmp = "0|514-276-5468|Savoir-faire Linux|144562458|empty"; CPPUNIT_ASSERT (Validator::isEqual (tmp, map_test ["144562436"])); - tmp = "2|136|Emmanuel Milou|747638765|Account:1239059899"; - CPPUNIT_ASSERT (Validator::isEqual (tmp, map_test ["747638685"])); - // the account ID does not correspond to a loaded account tmp = "1|5143848557|empty|775354987|empty"; CPPUNIT_ASSERT (Validator::isEqual (tmp, map_test ["775354456"])); diff --git a/sflphone-common/test/historytest.h b/sflphone-common/test/historytest.h index 84b1e7a5ec5a7720f7d3956180e36b034ef0ca8f..fac450afdfb0783b9bb770c48670501a2dc41f9b 100644 --- a/sflphone-common/test/historytest.h +++ b/sflphone-common/test/historytest.h @@ -54,13 +54,13 @@ class HistoryTest : public CppUnit::TestCase { */ CPPUNIT_TEST_SUITE (HistoryTest); CPPUNIT_TEST (test_create_history_path); - CPPUNIT_TEST (test_save_history_to_file); CPPUNIT_TEST (test_save_history_items_map); CPPUNIT_TEST (test_load_history_from_file); CPPUNIT_TEST (test_load_history_items_map); CPPUNIT_TEST (test_get_history_serialized); CPPUNIT_TEST (test_set_serialized_history); CPPUNIT_TEST (test_set_serialized_history_with_limit); + CPPUNIT_TEST (test_save_history_to_file); CPPUNIT_TEST_SUITE_END (); public: diff --git a/sflphone-common/test/main.cpp b/sflphone-common/test/main.cpp index 0823891c597351b8208f094ddc0247c75e0550ee..493366d68a55b1814ade0b8c912f02c3d2ab3ca9 100644 --- a/sflphone-common/test/main.cpp +++ b/sflphone-common/test/main.cpp @@ -30,10 +30,10 @@ #include <logger.h> #include <manager.h> - -#define CONFIG_SAMPLE "sflphonedrc-sample" +#include <constants.h> #include <cppunit/CompilerOutputter.h> +#include <cppunit/XmlOutputter.h> #include <cppunit/extensions/TestFactoryRegistry.h> #include <cppunit/ui/text/TextTestRunner.h> @@ -45,6 +45,7 @@ int main (int argc, char* argv[]) Logger::setDebugMode (true); int argvIndex = 1; + bool xmlOutput = false; if (argc > 1) { if (strcmp ("--help", argv[1]) == 0) { @@ -55,6 +56,7 @@ int main (int argc, char* argv[]) int testSuiteCount = suite->getChildTestCount(); printf ("Usage: test [OPTIONS] [TEST_SUITE]\n"); printf ("\nOptions:\n"); + printf (" --xml - Output results in an XML file, instead of standard output.\n"); printf (" --debug - Debug mode\n"); printf (" --help - Print help\n"); printf ("\nAvailable test suites:\n"); @@ -69,7 +71,13 @@ int main (int argc, char* argv[]) Logger::setDebugMode (true); _info ("Debug mode activated"); - } + + } else if (strcmp("--xml", argv[1]) == 0) { + argvIndex++; + + xmlOutput = true; + _info ("Using XML output"); + } } // Default test suite : all tests @@ -96,9 +104,16 @@ int main (int argc, char* argv[]) // Adds the test to the list of test to run CppUnit::TextTestRunner runner; runner.addTest (suite); - - // Change the default outputter to a compiler error format outputter - runner.setOutputter (new CppUnit::CompilerOutputter (&runner.result(), std::cerr)); + /* Specify XML output */ + std::ofstream outfile("cppunitresults.xml"); + + if (xmlOutput) { + CppUnit::XmlOutputter* outputter = new CppUnit::XmlOutputter(&runner.result(), outfile); + runner.setOutputter(outputter); + } else { + // Change the default outputter to a compiler error format outputter + runner.setOutputter (new CppUnit::CompilerOutputter (&runner.result(), std::cerr)); + } // Run the tests. bool wasSucessful = runner.run(); diff --git a/sflphone-common/test/ringtonetest.cpp b/sflphone-common/test/ringtonetest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9ddeb96949fd96b5b9c6b5335118be53c0a0f2da --- /dev/null +++ b/sflphone-common/test/ringtonetest.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +#include "ringtonetest.h" + +void RingtoneTest::testLoadWavefile() +{ + WavFile *wav = new WavFile(); + + // Test initial values + CPPUNIT_ASSERT (wav->isStarted() == false); + CPPUNIT_ASSERT (wav->getSize() == 0); + + // Test protection against wrong file name + CPPUNIT_ASSERT (wav->loadFile (std::string ("wrongfilename.wav"), NULL, 44100) == false); + + + + delete wav; + wav = NULL; +} diff --git a/sflphone-common/test/ringtonetest.h b/sflphone-common/test/ringtonetest.h new file mode 100644 index 0000000000000000000000000000000000000000..bef2e16662626648dde785a22e17e7652c73c6f4 --- /dev/null +++ b/sflphone-common/test/ringtonetest.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc. + * Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com> + * + * 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 3 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Additional permission under GNU GPL version 3 section 7: + * + * If you modify this program, or any covered work, by linking or + * combining it with the OpenSSL project's OpenSSL library (or a + * modified version of that library), containing parts covered by the + * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc. + * grants you additional permission to convey the resulting work. + * Corresponding Source for a non-source form of such a combination + * shall include the source code for the parts of OpenSSL used as well + * as that of the covered work. + */ + +/* + * @file ringtonetest.cpp + * @brief Regroups unitary tests related to the ringtones. + * Check if the wave file has been successfully loaded + */ + +#ifndef _RINGTONE_TEST_ +#define _RINGTONE_TEST_ + +// Cppunit import +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCaller.h> +#include <cppunit/TestCase.h> +#include <cppunit/TestSuite.h> + +#include <assert.h> + +// Application import +#include "manager.h" +#include "audio/sound/audiofile.h" +#include "global.h" +#include "user_cfg.h" + +class RingtoneTest: public CppUnit::TestFixture { + + /* + * Use cppunit library macros to add unit test the factory + */ + CPPUNIT_TEST_SUITE( RingtoneTest ); + CPPUNIT_TEST( testLoadWavefile ); + CPPUNIT_TEST_SUITE_END(); + +public: + /* + * Unit tests related to the audio preferences + */ + void testLoadWavefile(); + +}; +/* Register our test module */ +CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(RingtoneTest, "RingtoneTest"); +CPPUNIT_TEST_SUITE_REGISTRATION( RingtoneTest ); + +#endif diff --git a/sflphone-common/test/waveSample/M1F1-int16WE-AFsp.wav b/sflphone-common/test/waveSample/M1F1-int16WE-AFsp.wav new file mode 100644 index 0000000000000000000000000000000000000000..6df1c305809b5cee7a8fa4b07e28ee4dcbe524cb Binary files /dev/null and b/sflphone-common/test/waveSample/M1F1-int16WE-AFsp.wav differ diff --git a/sflphone-common/test/ymlParser.yml b/sflphone-common/test/ymlParser.yml new file mode 100644 index 0000000000000000000000000000000000000000..c63756336f815a62a8745e960d6263be9c047807 --- /dev/null +++ b/sflphone-common/test/ymlParser.yml @@ -0,0 +1,117 @@ +accounts: + - id: 1234 + alias: sfl-181 + username: 181 + password: sfl-181pw + hostname: sflphone.org + enable: true + type: sip + + - id: 2345 + alias: sfl-431 + username: 431 + password: alexandre + hostname: 192.168.50.3 + enable: true + type: sip + expire: 3600 + interface: lo + port: 5065 + mailbox: 97 + publishaddr: 127.0.0.1 + publishport: 5065 + sameaslocal: true + resolveonce: false + codecs: 0/9/110/111/112/ + credential: + count: 0 + srtp: + enable: true + keyexchange: sdes + rtpfallback: true + zrtp: + displaySas: true + displaySasOnce: false + helloHashEnabled: true + notSuppWarning: true + tls: + certificate: /home/msavard/Development/sflphone/sflphone-client-gnome/config.guess + calist: /home/msavard/Development/sflphone/sflphone-client-gnome/aclocal.m4 + ciphers: + enable: true + method: TLSv1 + timeout: 0 + password: + privatekey: /home/msavard/Development/sflphone/sflphone-client-gnome/config.log + requirecertif: true + server: + verifyclient: true + verifyserver: true + +addressbook: + photo: false + enabled: true + list: 1243608768.30329.0@emilou-desktop/1243456917.15690.23@emilou-desktop/ + max_results: 25 + business: true + home: false + mobile: false + +audio: + alsa: + cardin: 0 + cardout: 0 + cardout: 0 + framesize: 20 + plugin: default + smplrate: 44100 + pulse: + devicePlayback: + deviceRecord: + deviceRingtone: + recordpath: /home/msavard/Bureau + ringchoice: /usr/share/sflphone/ringtones/konga.ul + volumemic: 100 + volumespkr: 100 + +hooks: + iax2Enabled: false + numberAddPrefix: false + numberEnabled: false + sipEnabled: false + urlCommand: x-www-browser + urlSipField: X-sflphone-url + +preferences: + order: 1234/2345 + audioapi: 0 + dialpaddisplay: 0 + historyenabled: 1 + historylimit: 30 + historymaxCalls: 20 + notifyall: true + notifymails: false + zoneToneChoice: North America + registrationexpire: 180 + ringtonesenable: true + portnum: 5060 + searchbardisplay: true + starthidden: 0 + volumedisplay: 0 + windowheight: 332 + windowpopup: 0 + windowposition: 0 + windowposition: 24 + windowwidth: 240 + zeroconfenable: false + md5Hash: false + +voiplink: + playDtmf: true + playTones: true + pulseLength: 250 + sendDTMFas: 0 + stunenable: 0 + stunserver: stun.sflphone.org + symmetric: true + zidFile: sfl.zid \ No newline at end of file diff --git a/sippxml/g711a.pcap b/sippxml/g711a.pcap new file mode 100644 index 0000000000000000000000000000000000000000..bafea386f396eacbd14871f0156aed76df0166ee Binary files /dev/null and b/sippxml/g711a.pcap differ diff --git a/sippxml/simpleServiceRoute.xml b/sippxml/simpleServiceRoute.xml new file mode 100644 index 0000000000000000000000000000000000000000..f09cd05012249742044ad1ba0f43cce09a499de3 --- /dev/null +++ b/sippxml/simpleServiceRoute.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE scenario SYSTEM "sipp.dtd"> + +<scenario name="Basic Sipstone UAC"> + + <send retrans="500"> + <![CDATA[ + + INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0 + Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] + From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number] + To: sut <sip:[service]@[remote_ip]:[remote_port]> + Call-ID: [call_id] + CSeq: 1 INVITE + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Type: application/sdp + Content-Length: [len] + Route: <sip:sipp@[local_ip]:[local_port]> + + v=0 + o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] + s=- + c=IN IP[media_ip_type] [media_ip] + t=0 0 + m=audio [media_port] RTP/AVP 0 + a=rtpmap:0 PCMU/8000 + + ]]> + </send> + + <recv response="100" + optional="true"> + </recv> + + <recv response="183" optional="true"> + </recv> + + <recv response="200" rtd="true"> + </recv> + + <send> + <![CDATA[ + + ACK sip:[service]@[remote_ip]:[remote_port] SIP/2.0 + Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] + From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number] + To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param] + Call-ID: [call_id] + CSeq: 1 ACK + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Length: 0 + + ]]> + </send> + + <pause/> + + <send retrans="500"> + <![CDATA[ + + BYE sip:[service]@[remote_ip]:[remote_port] SIP/2.0 + Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch] + From: sipp <sip:sipp@[local_ip]:[local_port]>;tag=[call_number] + To: sut <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param] + Call-ID: [call_id] + CSeq: 2 BYE + Contact: sip:sipp@[local_ip]:[local_port] + Max-Forwards: 70 + Subject: Performance Test + Content-Length: 0 + + ]]> + </send> + + <recv response="200" crlf="true"> + </recv> + + <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> + + <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> + +</scenario> diff --git a/sippxml/testEarlyMedia.xml b/sippxml/testEarlyMedia.xml new file mode 100644 index 0000000000000000000000000000000000000000..28f34ff4f084dc598c77b2bba5b8ecead188ff89 --- /dev/null +++ b/sippxml/testEarlyMedia.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE scenario SYSTEM "sipp.dtd"> + +<!-- sudo sipp -sf testEarlyMedia.xml 127.0.0.1 -i 127.0.0.1 -p 5062 -l 1 -m 1 -mp 6000 --> + +<scenario name="Basic UAS responder"> + + <recv request="INVITE" crlf="true"> + </recv> + + + <send> + <![CDATA[ + + SIP/2.0 100 Ringing + [last_Via:] + [last_From:] + [last_To:];tag=[call_number] + [last_Call-ID:] + [last_CSeq:] + Contact: <sip:[local_ip]:[local_port];transport=[transport]> + Content-Length: 0 + + ]]> + </send> + + <send> + <![CDATA[ + + SIP/2.0 183 Trying + [last_Via:] + [last_From:] + [last_To:];tag=[call_number] + [last_Call-ID:] + [last_CSeq:] + Contact: <sip:[local_ip]:[local_port];transport=[transport]> + Content-Type: application/sdp + Content-Length: [len] + + v=0 + o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip] + s=- + c=IN IP[media_ip_type] [media_ip] + t=0 0 + m=audio [media_port] RTP/AVP 0 + a=rtpmap:0 PCMU/8000 + + ]]> + </send> + + <!-- Play a pre-recorded PCAP file (RTP stream) --> + <nop> + <action> + <exec play_pcap_audio="g711a.pcap"/> + </action> + </nop> + + <!-- Pause 8 seconds, which is approximately the duration of the --> + <!-- PCAP file --> + <pause milliseconds="8000"/> + + <send retrans="500"> + <![CDATA[ + + SIP/2.0 200 OK + [last_Via:] + [last_From:] + [last_To:];tag=[call_number] + [last_Call-ID:] + [last_CSeq:] + Contact: <sip:[local_ip]:[local_port];transport=[transport]> + Content-Length: [len] + + ]]> + </send> + + <recv request="ACK" + optional="true" + rtd="true" + crlf="true"> + </recv> + + <recv request="BYE"> + </recv> + + <send> + <![CDATA[ + + SIP/2.0 200 OK + [last_Via:] + [last_From:] + [last_To:] + [last_Call-ID:] + [last_CSeq:] + Contact: <sip:[local_ip]:[local_port];transport=[transport]> + Content-Length: 0 + + ]]> + </send> + + <pause milliseconds="4000"/> + + + <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/> + + <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/> + +</scenario> diff --git a/sippxml/voice b/sippxml/voice new file mode 100644 index 0000000000000000000000000000000000000000..c881cf2d1b97c326d0f5d78ad4beebde51bd4b15 Binary files /dev/null and b/sippxml/voice differ diff --git a/tools/build-system/build-osc.sh b/tools/build-system/build-osc.sh index 8735ba83dfde2e019d8033e173f3676ac67cc4af..fac03deb08b764095b50f0f20b40d2034f4c5bf4 100755 --- a/tools/build-system/build-osc.sh +++ b/tools/build-system/build-osc.sh @@ -7,23 +7,21 @@ # Author: Julien Bonjean (julien@bonjean.info) # # Creation Date: 2009-11-02 -# Last Modified: +# Last Modified: 2010-05-27 17:39:58 -0400 ##################################################### ROOT_DIR=${HOME} OSC_REPOSITORY="${ROOT_DIR}/sflphone-osc/home:jbonjean:sflphone" -WORKING_DIR="${ROOT_DIR}/sflphone-build-repository/tools/build-system" -OSC_DIR="${WORKING_DIR}/osc" - LAUNCHPAD_PACKAGES=( "sflphone-client-gnome" "sflphone-common" ) #LAUNCHPAD_PACKAGES=( "sflphone-client-gnome" ) #LAUNCHPAD_PACKAGES=( "sflphone-common" ) REFERENCE_REPOSITORY="${ROOT_DIR}/sflphone-source-repository" +OSC_DIR="${REFERENCE_REPOSITORY}/tools/build-system/osc" -SOFTWARE_VERSION="0.9.7.rc2" +SOFTWARE_VERSION="0.9.8.3" VERSION_INDEX=1 diff --git a/tools/build-system/launch-build-machine-2.sh b/tools/build-system/launch-build-machine-2.sh index 12f8760e79c1de83f177606a64127b320fba516a..6ced3b75ee085b476231768865bf83d2c9b44293 100755 --- a/tools/build-system/launch-build-machine-2.sh +++ b/tools/build-system/launch-build-machine-2.sh @@ -7,7 +7,7 @@ # Author: Julien Bonjean (julien@bonjean.info) # # Creation Date: 2009-10-20 -# Last Modified: 2009-12-15 18:16:50 -0500 +# Last Modified: 2010-04-22 16:42:57 -0400 ##################################################### #set -x @@ -16,10 +16,12 @@ IS_RELEASE= VERSION_INDEX="1" +IS_KDE_CLIENT= DO_PUSH=1 DO_LOGGING=1 DO_UPLOAD=1 SNAPSHOT_TAG=`date +%Y%m%d` +TAG_NAME_PREFIX= LAUNCHPAD_PACKAGES=( "sflphone-client-gnome" "sflphone-common" ) @@ -37,6 +39,7 @@ do echo "Options :" echo " --skip-push" echo " --skip-upload" + echo " --kde-client" echo " --no-logging" echo " --release" echo " --version-index=[1,2,...]" @@ -46,6 +49,8 @@ do unset DO_PUSH;; --skip-upload) unset DO_UPLOAD;; + --kde-client) + IS_KDE_CLIENT=1;; --no-logging) unset DO_LOGGING;; --release) @@ -89,6 +94,10 @@ else echo "Snapshot mode" fi +if [ ${IS_KDE_CLIENT} ]; then + TAG_NAME_PREFIX="kde." +fi + ######################### # COMMON PART ######################### @@ -104,15 +113,26 @@ fi echo "Retrieve build info" # retrieve info we may need -CURRENT_RELEASE_TAG_NAME=`git tag -l "[0-9]\.[0-9]\.[0-9]\.*" | tail -n 1` -PREVIOUS_RELEASE_TAG_NAME=`git tag -l "[0-9]\.[0-9]\.[0-9]\.*" | tail -n 2 | sed -n '1p;1q'` +if [ ${IS_KDE_CLIENT} ]; then + TAG_NAME_PREFIX="kde." + LAUNCHPAD_PACKAGES=( "sflphone-client-kde" ) +fi +CURRENT_RELEASE_TAG_NAME=`git tag -l "${TAG_NAME_PREFIX}[0-9]\.[0-9]\.[0-9]\.*" | tail -n 1` +PREVIOUS_RELEASE_TAG_NAME=`git tag -l "${TAG_NAME_PREFIX}[0-9]\.[0-9]\.[0-9]\.*" | tail -n 2 | sed -n '1p;1q'` CURRENT_RELEASE_COMMIT_HASH=`git show --pretty=format:"%H" -s ${CURRENT_RELEASE_TAG_NAME} | tail -n 1` PREVIOUS_RELEASE_COMMIT_HASH=`git show --pretty=format:"%H" -s ${PREVIOUS_RELEASE_TAG_NAME} | tail -n 1` CURRENT_COMMIT=`git show --pretty=format:"%H" -s | tail -n 1` CURRENT_RELEASE_TYPE=${CURRENT_RELEASE_TAG_NAME##*.} PREVIOUS_RELEASE_TYPE=${PREVIOUS_RELEASE_TAG_NAME##*.} -CURRENT_RELEASE_VERSION=${CURRENT_RELEASE_TAG_NAME%*.*} -PREVIOUS_VERSION=${PREVIOUS_RELEASE_TAG_NAME%*.*} +if [ ${IS_KDE_CLIENT} ]; then + CURRENT_RELEASE_VERSION=${CURRENT_RELEASE_TAG_NAME%.*} + CURRENT_RELEASE_VERSION=${CURRENT_RELEASE_VERSION#*.} + PREVIOUS_VERSION=${PREVIOUS_RELEASE_TAG_NAME%.*} + PREVIOUS_VERSION=${PREVIOUS_VERSION#*.} +else + CURRENT_RELEASE_VERSION=${CURRENT_RELEASE_TAG_NAME%.*} + PREVIOUS_VERSION=${PREVIOUS_RELEASE_TAG_NAME%.*} +fi cd ${LAUNCHPAD_DIR} diff --git a/tools/build-system/launchpad/dput.conf b/tools/build-system/launchpad/dput.conf index ea85aa390ad912a626508ec49c3f2e0ec6e5d98d..8566a50799474d4c2c1b3251c63d00a75efca81c 100644 --- a/tools/build-system/launchpad/dput.conf +++ b/tools/build-system/launchpad/dput.conf @@ -12,6 +12,13 @@ incoming = ~savoirfairelinux/sflphone-testing/ubuntu/karmic login = anonymous allow_unsigned_uploads = 0 +[sflphone-lucid] +fqdn = ppa.launchpad.net +method = ftp +incoming = ~savoirfairelinux/sflphone-testing/ubuntu/lucid +login = anonymous +allow_unsigned_uploads = 0 + [sflphone-nightly-jaunty] fqdn = ppa.launchpad.net method = ftp diff --git a/tools/build-system/launchpad/mozilla-telify-sflphone/debian/changelog b/tools/build-system/launchpad/mozilla-telify-sflphone/debian/changelog index e368436b93aa5b42f1181e9c9e4022ec9e0f929f..23510a03d7a2e4ceae2c28fb88258277cb08db73 100644 --- a/tools/build-system/launchpad/mozilla-telify-sflphone/debian/changelog +++ b/tools/build-system/launchpad/mozilla-telify-sflphone/debian/changelog @@ -1,3 +1,10 @@ +mozilla-telify-sflphone (1.0) unstable; urgency=low + + [ Julien Bonjean ] + * Package update + + -- Julien Bonjean <julien.bonjean@savoirfairelinux.com> Fri, 21 Avr 2010 19:51:54 +0100 + mozilla-telify-sflphone (0.4.7.3) unstable; urgency=low [ Julien Bonjean ] diff --git a/tools/build-system/launchpad/mozilla-telify-sflphone/debian/files b/tools/build-system/launchpad/mozilla-telify-sflphone/debian/files index 8ebe49a9909755509943dd3161a8cb96e3acf7ec..320b727519610179c97214659e4e3be20f8cebc3 100644 --- a/tools/build-system/launchpad/mozilla-telify-sflphone/debian/files +++ b/tools/build-system/launchpad/mozilla-telify-sflphone/debian/files @@ -1 +1 @@ -mozilla-telify-sflphone_0.4.7.3_all.deb web optional +mozilla-telify-sflphone_1.0_all.deb web optional diff --git a/tools/build-system/launchpad/mozilla-telify-sflphone/debian/rules b/tools/build-system/launchpad/mozilla-telify-sflphone/debian/rules index 0e8b875eb41ef0f3b085984d5b6f7cdde67c6181..8522b9ee026d450490d0168c1db7a97a389fa2e2 100755 --- a/tools/build-system/launchpad/mozilla-telify-sflphone/debian/rules +++ b/tools/build-system/launchpad/mozilla-telify-sflphone/debian/rules @@ -3,7 +3,7 @@ # Uncomment this to turn on verbose mode. export DH_VERBOSE=1 -VERSION="0.4.7.3" +VERSION="1.0" configure: configure-stamp configure-stamp: diff --git a/tools/build-system/launchpad/sflphone-client-kde/debian/control.jaunty b/tools/build-system/launchpad/sflphone-client-kde/debian/control.jaunty new file mode 100644 index 0000000000000000000000000000000000000000..a4e6a266195dad90c9132c41a8373ea5bf84ae16 --- /dev/null +++ b/tools/build-system/launchpad/sflphone-client-kde/debian/control.jaunty @@ -0,0 +1,20 @@ +Source: sflphone-client-kde +Maintainer: SavoirFaireLinux Inc <julien.bonjean@savoirfairelinux.com> +Section: kde +Priority: optional +Build-Depends: debhelper, cmake, kdepimlibs5-dev, libcommoncpp2-dev, libqt4-dev +Standards-Version: 3.7.3 + +Package: sflphone-client-kde +Priority: optional +Architecture: i386 +Depends: sflphone-common (>=${source:Version}), libcommoncpp2-1.6-0, kdepimlibs5, libqt4-dbus, libqt4-svg, libqtgui4 +Replaces: sflphone +Conflicts: sflphone +Homepage: http://www.sflphone.org +Description: KDE client for SFLphone + Provide a KDE client for SFLphone. + SFLphone is meant to be a robust enterprise-class desktop phone. + SFLphone is released under the GNU General Public License. + SFLphone is being developed by the global community, and maintained by + Savoir-faire Linux, a Montreal, Quebec, Canada-based Linux consulting company. diff --git a/tools/build-system/launchpad/sflphone-client-kde/debian/control.karmic b/tools/build-system/launchpad/sflphone-client-kde/debian/control.karmic new file mode 100644 index 0000000000000000000000000000000000000000..a4e6a266195dad90c9132c41a8373ea5bf84ae16 --- /dev/null +++ b/tools/build-system/launchpad/sflphone-client-kde/debian/control.karmic @@ -0,0 +1,20 @@ +Source: sflphone-client-kde +Maintainer: SavoirFaireLinux Inc <julien.bonjean@savoirfairelinux.com> +Section: kde +Priority: optional +Build-Depends: debhelper, cmake, kdepimlibs5-dev, libcommoncpp2-dev, libqt4-dev +Standards-Version: 3.7.3 + +Package: sflphone-client-kde +Priority: optional +Architecture: i386 +Depends: sflphone-common (>=${source:Version}), libcommoncpp2-1.6-0, kdepimlibs5, libqt4-dbus, libqt4-svg, libqtgui4 +Replaces: sflphone +Conflicts: sflphone +Homepage: http://www.sflphone.org +Description: KDE client for SFLphone + Provide a KDE client for SFLphone. + SFLphone is meant to be a robust enterprise-class desktop phone. + SFLphone is released under the GNU General Public License. + SFLphone is being developed by the global community, and maintained by + Savoir-faire Linux, a Montreal, Quebec, Canada-based Linux consulting company. diff --git a/tools/build-system/launchpad/sflphone-client-kde/debian/control.lucid b/tools/build-system/launchpad/sflphone-client-kde/debian/control.lucid new file mode 100644 index 0000000000000000000000000000000000000000..a4e6a266195dad90c9132c41a8373ea5bf84ae16 --- /dev/null +++ b/tools/build-system/launchpad/sflphone-client-kde/debian/control.lucid @@ -0,0 +1,20 @@ +Source: sflphone-client-kde +Maintainer: SavoirFaireLinux Inc <julien.bonjean@savoirfairelinux.com> +Section: kde +Priority: optional +Build-Depends: debhelper, cmake, kdepimlibs5-dev, libcommoncpp2-dev, libqt4-dev +Standards-Version: 3.7.3 + +Package: sflphone-client-kde +Priority: optional +Architecture: i386 +Depends: sflphone-common (>=${source:Version}), libcommoncpp2-1.6-0, kdepimlibs5, libqt4-dbus, libqt4-svg, libqtgui4 +Replaces: sflphone +Conflicts: sflphone +Homepage: http://www.sflphone.org +Description: KDE client for SFLphone + Provide a KDE client for SFLphone. + SFLphone is meant to be a robust enterprise-class desktop phone. + SFLphone is released under the GNU General Public License. + SFLphone is being developed by the global community, and maintained by + Savoir-faire Linux, a Montreal, Quebec, Canada-based Linux consulting company. diff --git a/tools/build-system/launchpad/sflphone-common/debian/control.jaunty b/tools/build-system/launchpad/sflphone-common/debian/control.jaunty index 8700719c003eb8c46780ca12aa608dd1639490b2..246bf4f56ce832d182e0efab19ca6be01bcc3ecc 100644 --- a/tools/build-system/launchpad/sflphone-common/debian/control.jaunty +++ b/tools/build-system/launchpad/sflphone-common/debian/control.jaunty @@ -2,13 +2,13 @@ Source: sflphone-common Maintainer: SavoirFaireLinux Inc <julien.bonjean@savoirfairelinux.com> Section: gnome Priority: optional -Build-Depends: debhelper, libgcc1 , autoconf, automake, libpulse-dev, libsamplerate0-dev, libcommoncpp2-dev, libccrtp-dev, libgsm1-dev, libspeex-dev, libtool, libdbus-1-dev, libasound2-dev, libspeexdsp-dev, uuid-dev, libexpat1-dev, libzrtpcpp-dev, libssl-dev, libpcre3-dev +Build-Depends: debhelper, libgcc1 , autoconf, automake, libpulse-dev, libsamplerate0-dev, libcommoncpp2-dev, libccrtp-dev, libgsm1-dev, libspeex-dev, libtool, libdbus-1-dev, libasound2-dev, libspeexdsp-dev, uuid-dev, libexpat1-dev, libzrtpcpp-dev, libssl-dev, libpcre3-dev, libyaml-dev Standards-Version: 3.7.3 Package: sflphone-common Priority: optional Architecture: any -Depends: libsamplerate0, libexpat1 , libc6, libcommoncpp2-1.6-0, libgsm1, libspeex1, libdbus-1-3, libasound2, libpulse0, libccrtp1-1.6-1, libspeexdsp1, libzrtpcpp-1.3-0, libssl0.9.8, libpcre3 +Depends: libsamplerate0, libexpat1 , libc6, libcommoncpp2-1.6-0, libgsm1, libspeex1, libdbus-1-3, libasound2, libpulse0, libccrtp1-1.6-1, libspeexdsp1, libzrtpcpp-1.3-0, libssl0.9.8, libpcre3, libyaml-0-2 Replaces: sflphone Conflicts: sflphone Homepage: http://www.sflphone.org diff --git a/tools/build-system/launchpad/sflphone-common/debian/control.karmic b/tools/build-system/launchpad/sflphone-common/debian/control.karmic index 177306ed35bf7cae2a8d1f2e7bc03a3772cc24c9..9b1561ed747d9add075108e2345cfbc87df06df3 100644 --- a/tools/build-system/launchpad/sflphone-common/debian/control.karmic +++ b/tools/build-system/launchpad/sflphone-common/debian/control.karmic @@ -2,13 +2,13 @@ Source: sflphone-common Maintainer: SavoirFaireLinux Inc <julien.bonjean@savoirfairelinux.com> Section: gnome Priority: optional -Build-Depends: debhelper, libgcc1 , autoconf, automake, libpulse-dev, libsamplerate0-dev, libcommoncpp2-dev, libccrtp-dev, libgsm1-dev, libspeex-dev, libtool, libdbus-1-dev, libasound2-dev, libspeexdsp-dev, uuid-dev, libexpat1-dev, libzrtpcpp-dev, libssl-dev, libpcre3-dev +Build-Depends: debhelper, libgcc1 , autoconf, automake, libpulse-dev, libsamplerate0-dev, libcommoncpp2-dev, libccrtp-dev, libgsm1-dev, libspeex-dev, libtool, libdbus-1-dev, libasound2-dev, libspeexdsp-dev, uuid-dev, libexpat1-dev, libzrtpcpp-dev, libssl-dev, libpcre3-dev, libyaml-dev Standards-Version: 3.7.3 Package: sflphone-common Priority: optional Architecture: any -Depends: libsamplerate0, libexpat1 , libc6, libccgnu2-1.7-0, libgsm1, libspeex1, libdbus-1-3, libasound2, libpulse0, libccrtp1-1.7-0, libspeexdsp1, libzrtpcpp-1.4-0, libssl0.9.8, libpcre3 +Depends: libsamplerate0, libexpat1 , libc6, libccgnu2-1.7-0, libgsm1, libspeex1, libdbus-1-3, libasound2, libpulse0, libccrtp1-1.7-0, libspeexdsp1, libzrtpcpp-1.4-0, libssl0.9.8, libpcre3, libyaml-0-2 Replaces: sflphone Conflicts: sflphone Homepage: http://www.sflphone.org diff --git a/tools/build-system/launchpad/sflphone-common/debian/control.lucid b/tools/build-system/launchpad/sflphone-common/debian/control.lucid index 177306ed35bf7cae2a8d1f2e7bc03a3772cc24c9..9b1561ed747d9add075108e2345cfbc87df06df3 100644 --- a/tools/build-system/launchpad/sflphone-common/debian/control.lucid +++ b/tools/build-system/launchpad/sflphone-common/debian/control.lucid @@ -2,13 +2,13 @@ Source: sflphone-common Maintainer: SavoirFaireLinux Inc <julien.bonjean@savoirfairelinux.com> Section: gnome Priority: optional -Build-Depends: debhelper, libgcc1 , autoconf, automake, libpulse-dev, libsamplerate0-dev, libcommoncpp2-dev, libccrtp-dev, libgsm1-dev, libspeex-dev, libtool, libdbus-1-dev, libasound2-dev, libspeexdsp-dev, uuid-dev, libexpat1-dev, libzrtpcpp-dev, libssl-dev, libpcre3-dev +Build-Depends: debhelper, libgcc1 , autoconf, automake, libpulse-dev, libsamplerate0-dev, libcommoncpp2-dev, libccrtp-dev, libgsm1-dev, libspeex-dev, libtool, libdbus-1-dev, libasound2-dev, libspeexdsp-dev, uuid-dev, libexpat1-dev, libzrtpcpp-dev, libssl-dev, libpcre3-dev, libyaml-dev Standards-Version: 3.7.3 Package: sflphone-common Priority: optional Architecture: any -Depends: libsamplerate0, libexpat1 , libc6, libccgnu2-1.7-0, libgsm1, libspeex1, libdbus-1-3, libasound2, libpulse0, libccrtp1-1.7-0, libspeexdsp1, libzrtpcpp-1.4-0, libssl0.9.8, libpcre3 +Depends: libsamplerate0, libexpat1 , libc6, libccgnu2-1.7-0, libgsm1, libspeex1, libdbus-1-3, libasound2, libpulse0, libccrtp1-1.7-0, libspeexdsp1, libzrtpcpp-1.4-0, libssl0.9.8, libpcre3, libyaml-0-2 Replaces: sflphone Conflicts: sflphone Homepage: http://www.sflphone.org diff --git a/tools/build-system/osc/sflphone-client-gnome.spec b/tools/build-system/osc/sflphone-client-gnome.spec index dba4cd8ebbdf090931c142a83b961ed2299b0805..af37d9b0ccc98e2778aa777a0a1212dc94c8d150 100644 --- a/tools/build-system/osc/sflphone-client-gnome.spec +++ b/tools/build-system/osc/sflphone-client-gnome.spec @@ -24,6 +24,7 @@ BuildRoot: %{_tmppath}/%{name} Source0: sflphone-client-gnome-%{version}.tar.gz %if %{defined suse_version} +BuildRequires: scrollkeeper BuildRequires: update-desktop-files BuildRequires: liblog4c-devel BuildRequires: dbus-1-glib-devel @@ -32,10 +33,12 @@ BuildRequires: libgnomeui-devel %endif %if %{defined fedora_version} +BuildRequires: rarian-compat BuildRequires: log4c-devel BuildRequires: dbus-glib-devel BuildRequires: gnome-doc-utils BuildRequires: libgnomeui-devel +BuildRequires: gettext # fix libproxy-pac expansion error BuildRequires: libproxy-webkit # fix PolicyKit-authentication-agent expansion error @@ -97,6 +100,7 @@ Authors: %build +export SUSE_ASNEEDED=0 # fix opensuse linking issue (Since 11.2 uses default --as-needed for linking, the order of libraries is important) ./autogen.sh ./configure --prefix=%{_prefix} make -j diff --git a/tools/build-system/osc/sflphone-client-kde.spec b/tools/build-system/osc/sflphone-client-kde.spec index a6d78bea5fbb128152a9bb67b2be96f7aac7416d..c3a9c2de2a4c138bf8526f8d0f460d2634694e00 100644 --- a/tools/build-system/osc/sflphone-client-kde.spec +++ b/tools/build-system/osc/sflphone-client-kde.spec @@ -13,8 +13,8 @@ Name: sflphone-client-kde License: GNU General Public License (GPL) Group: Productivity/Networking/System Summary: KDE client for SFLphone -Version: 0.9.6 -Release: opensuse +Version: VERSION +Release: VERSION_INDEX%{?dist} URL: http://www.sflphone.org/ Vendor: Savoir-faire Linux Packager: Julien Bonjean <julien.bonjean@savoirfairelinux.com> diff --git a/tools/build-system/osc/sflphone-common.spec b/tools/build-system/osc/sflphone-common.spec index d44f94103e8e4e61fefc2be0a03d0e2b4a9f58c4..387fa4c52524584d9e040ac0536c12bca1354699 100644 --- a/tools/build-system/osc/sflphone-common.spec +++ b/tools/build-system/osc/sflphone-common.spec @@ -13,8 +13,8 @@ Name: sflphone-common License: GNU General Public License (GPL) Group: System Environment/Daemons Summary: SIP and IAX2 compatible softphone - Core -Version: VERSION -Release: VERSION_INDEX%{?dist} +Version: VERSION +Release: VERSION_INDEX%{?dist} URL: http://www.sflphone.org/ Vendor: Savoir-faire Linux Packager: Julien Bonjean <julien.bonjean@savoirfairelinux.com> @@ -24,13 +24,10 @@ Source0: sflphone-common-%{version}.tar.gz BuildRequires: speex-devel BuildRequires: gcc-c++ BuildRequires: expat -BuildRequires: alsa-devel -BuildRequires: dbus-1-devel BuildRequires: libzrtpcpp-devel BuildRequires: commoncpp2-devel BuildRequires: libsamplerate-devel - %if %{defined suse_version} BuildRequires: libpulse-devel BuildRequires: libccrtp-devel @@ -40,6 +37,9 @@ BuildRequires: libcppunit-devel BuildRequires: libuuid-devel BuildRequires: libopenssl-devel BuildRequires: libexpat0 +BuildRequires: alsa-devel +BuildRequires: dbus-1-devel +BuildRequires: pcre-devel %endif %if %{defined fedora_version} @@ -49,8 +49,11 @@ BuildRequires: openssl BuildRequires: expat-devel BuildRequires: ccrtp-devel BuildRequires: cppunit-devel -BuildRequires: uuid-devel +BuildRequires: libuuid-devel BuildRequires: gsm-devel +BuildRequires: alsa-lib-devel +BuildRequires: dbus-devel +BuildRequires: pcre-devel %endif Requires: libsamplerate @@ -96,6 +99,7 @@ Authors: %setup -q %build +export SUSE_ASNEEDED=0 # fix opensuse linking issue (Since 11.2 uses default --as-needed for linking, the order of libraries is important) cd libs/pjproject ./autogen.sh ./configure --prefix=%{_prefix} --libdir=%{_libdir} @@ -125,7 +129,6 @@ make clean %dir %{_libdir}/sflphone/plugins %dir %{_prefix}/share/sflphone %dir %{_prefix}/share/sflphone/ringtones -%{_libdir}/sflphone/libdbus-* %{_libdir}/sflphone/codecs/* %{_libdir}/sflphone/plugins/* %{_prefix}/share/dbus-1/services/org.sflphone.* diff --git a/tools/mozilla-telify-sflphone/telify-0.4.7.3-fx.xpi b/tools/mozilla-telify-sflphone/telify-1.0-fx.xpi similarity index 83% rename from tools/mozilla-telify-sflphone/telify-0.4.7.3-fx.xpi rename to tools/mozilla-telify-sflphone/telify-1.0-fx.xpi index ec1eff1fe541400731f1b2e5b6e33a30c8cd9a4a..8df2b63f5b8622d44eac232ed72b6d7699e54f23 100644 Binary files a/tools/mozilla-telify-sflphone/telify-0.4.7.3-fx.xpi and b/tools/mozilla-telify-sflphone/telify-1.0-fx.xpi differ