diff --git a/sflphone-client-gnome/src/actions.c b/sflphone-client-gnome/src/actions.c index f5d353f063fff3e5259b5d40204eef69f691cfa5..1d52bcf2a268a7dccaaeafe8579ef98942bdc84a 100644 --- a/sflphone-client-gnome/src/actions.c +++ b/sflphone-client-gnome/src/actions.c @@ -31,6 +31,17 @@ #include <sys/types.h> #include <unistd.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <resolv.h> + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <linux/if.h> + + + GHashTable * ip2ip_profile=NULL; void @@ -1305,7 +1316,6 @@ void sflphone_save_history (void) void sflphone_srtp_sdes_on(callable_obj_t * c) { - DEBUG("*************** Srtp SDES ON *************"); c->_srtp_state = SRTP_STATE_SDES_SUCCESS; @@ -1403,3 +1413,37 @@ sflphone_call_state_changed( callable_obj_t * c, const gchar * description, cons calltree_update_call(current_calls, c, NULL); update_actions(); } + + +void sflphone_get_interface_addr_from_name(char *iface_name, char **iface_addr) { + + struct ifreq ifr; + int fd; + int err; + // static char iface_addr[18]; + char *tmp_addr; + + struct sockaddr_in *saddr_in; + struct in_addr *addr_in; + + if((fd = socket (AF_INET, SOCK_DGRAM,0)) < 0) + DEBUG("getInterfaceAddrFromName error could not open socket\n"); + + memset (&ifr, 0, sizeof (struct ifreq)); + + strcpy (ifr.ifr_name, iface_name); + ifr.ifr_addr.sa_family = AF_INET; + + if((err = ioctl(fd, SIOCGIFADDR, &ifr)) < 0) + DEBUG("getInterfaceAddrFromName use default interface (0.0.0.0)\n"); + + + saddr_in = (struct sockaddr_in *)&ifr.ifr_addr; + addr_in = &(saddr_in->sin_addr); + + tmp_addr = (char *)addr_in; + + snprintf(*iface_addr, sizeof(*iface_addr), "%d.%d.%d.%d", + UC(tmp_addr[0]), UC(tmp_addr[1]), UC(tmp_addr[2]), UC(tmp_addr[3])); + +} diff --git a/sflphone-client-gnome/src/actions.h b/sflphone-client-gnome/src/actions.h index 6cf10d932fc6b6a9158e2e12aa08d92e9e621720..2d956ddb8073899245301cc042904f1cfb91ceb6 100644 --- a/sflphone-client-gnome/src/actions.h +++ b/sflphone-client-gnome/src/actions.h @@ -30,6 +30,8 @@ #include <errors.h> #include <conference_obj.h> +#define UC(b) (((int)b)&0xff) + /** @file actions.h * @brief General functions that change the state of the application. * All of these functions are called when dbus signals are triggered. Exceptions @@ -284,5 +286,8 @@ void sflphone_request_go_clear(void); */ void sflphone_call_state_changed(callable_obj_t * c, const gchar * description, const guint code); - +/** + * Resolve an interface address given its name + */ +void sflphone_get_interface_addr_from_name(char *iface_name, char **iface_addr); #endif diff --git a/sflphone-client-gnome/src/config/accountconfigdialog.c b/sflphone-client-gnome/src/config/accountconfigdialog.c index 28f45737aec30f5609a225de89a0c7e8a63b9edf..5fd6c4cc7c0e6aab00e85adaed59ce52bf1de3e1 100644 --- a/sflphone-client-gnome/src/config/accountconfigdialog.c +++ b/sflphone-client-gnome/src/config/accountconfigdialog.c @@ -67,6 +67,7 @@ GtkWidget * advancedZrtpButton; GtkWidget * keyExchangeCombo; GtkWidget * useSipTlsCheckBox; +GtkWidget * localAddressEntry; GtkWidget * publishedAddressEntry; GtkWidget * localAddressLabel; GtkWidget * localAddressCombo; @@ -562,16 +563,20 @@ static local_interface_changed_cb(GtkWidget * widget, gpointer data UNUSED) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(sameAsLocalRadioButton))) { - gchar *local_interface; - gchar *local_address; + gchar *local_iface_name; + gchar *local_iface_addr; + local_iface_addr = g_malloc(36); - local_interface = (gchar *) gtk_combo_box_get_active_text (GTK_COMBO_BOX (localAddressCombo)); - local_address = dbus_get_address_from_interface_name (local_interface); + 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); - gtk_entry_set_text (GTK_ENTRY(publishedAddressEntry), local_address); + 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); } } @@ -646,6 +651,7 @@ static same_as_local_cb(GtkWidget * widget, gpointer data UNUSED) gchar * local_address; local_interface = (gchar *) gtk_combo_box_get_active_text(GTK_COMBO_BOX(localAddressCombo)); + // sflphone_get_interface_addr_from_name((char *)local_interface); local_address = dbus_get_address_from_interface_name(local_interface); gtk_entry_set_text(GTK_ENTRY(publishedAddressEntry), local_address); @@ -858,118 +864,137 @@ GtkWidget * create_security_tab (account_t **a) GtkWidget* create_registration_expire (account_t **a) { - GtkWidget *table, *frame, *label; - - gchar *resolve_once=NULL, *account_expire=NULL; - - if (*a) { - resolve_once = g_hash_table_lookup ((*a)->properties, ACCOUNT_RESOLVE_ONCE); - account_expire = g_hash_table_lookup ((*a)->properties, ACCOUNT_REGISTRATION_EXPIRE); - } - - gnome_main_section_new_with_table (_("Registration"), &frame, &table, 2, 3); - gtk_container_set_border_width (GTK_CONTAINER(table), 10); - gtk_table_set_row_spacings (GTK_TABLE (table), 5); - - label = gtk_label_new_with_mnemonic (_("Registration expire")); - gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - expireSpinBox = gtk_spin_button_new_with_range (1, 65535, 1); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), expireSpinBox); - gtk_spin_button_set_value (GTK_SPIN_BUTTON (expireSpinBox), g_ascii_strtod (account_expire, NULL)); - gtk_table_attach_defaults (GTK_TABLE (table), expireSpinBox, 1, 2, 0, 1); + GtkWidget *table, *frame, *label; + gchar *resolve_once=NULL, *account_expire=NULL; - entryResolveNameOnlyOnce = gtk_check_button_new_with_mnemonic (_("_Comply with RFC 3263")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (entryResolveNameOnlyOnce), - g_strcasecmp (resolve_once,"false") == 0 ? TRUE: FALSE); - gtk_table_attach_defaults (GTK_TABLE (table), entryResolveNameOnlyOnce, 0, 2, 1, 2); - gtk_widget_set_sensitive (GTK_WIDGET (entryResolveNameOnlyOnce ) , TRUE ); + if (*a) { + resolve_once = g_hash_table_lookup ((*a)->properties, ACCOUNT_RESOLVE_ONCE); + account_expire = g_hash_table_lookup ((*a)->properties, ACCOUNT_REGISTRATION_EXPIRE); + } - return frame; + gnome_main_section_new_with_table (_("Registration"), &frame, &table, 2, 3); + gtk_container_set_border_width (GTK_CONTAINER(table), 10); + gtk_table_set_row_spacings (GTK_TABLE (table), 5); + + label = gtk_label_new_with_mnemonic (_("Registration expire")); + gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1); + gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); + expireSpinBox = gtk_spin_button_new_with_range (1, 65535, 1); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), expireSpinBox); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (expireSpinBox), g_ascii_strtod (account_expire, NULL)); + gtk_table_attach_defaults (GTK_TABLE (table), expireSpinBox, 1, 2, 0, 1); + + + entryResolveNameOnlyOnce = gtk_check_button_new_with_mnemonic (_("_Comply with RFC 3263")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (entryResolveNameOnlyOnce), + g_strcasecmp (resolve_once,"false") == 0 ? TRUE: FALSE); + gtk_table_attach_defaults (GTK_TABLE (table), entryResolveNameOnlyOnce, 0, 2, 1, 2); + gtk_widget_set_sensitive (GTK_WIDGET (entryResolveNameOnlyOnce ) , TRUE ); + + return frame; } GtkWidget* create_network (account_t **a) { + + GtkWidget *table, *frame, *label; + gchar *local_interface, *local_port; - GtkWidget *table, *frame, *label; - gchar *local_interface, *local_port; + if (*a) { + local_interface = g_hash_table_lookup ((*a)->properties, LOCAL_INTERFACE); + local_port = g_hash_table_lookup ((*a)->properties, LOCAL_PORT); + } - if (*a) { - local_interface = g_hash_table_lookup ((*a)->properties, LOCAL_INTERFACE); - local_port = g_hash_table_lookup ((*a)->properties, LOCAL_PORT); + gnome_main_section_new_with_table (_("Network Interface"), &frame, &table, 2, 3); + gtk_container_set_border_width (GTK_CONTAINER(table), 10); + gtk_table_set_row_spacings( GTK_TABLE(table), 5); + + /** + * Retreive the list of IP interface from the + * the daemon and build the combo box. + */ + + GtkListStore * ipInterfaceListStore; + GtkTreeIter iter; + + ipInterfaceListStore = gtk_list_store_new( 1, G_TYPE_STRING ); + label = gtk_label_new_with_mnemonic (_("Local address")); + gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); + + GtkTreeIter current_local_iface_iter = iter; + gchar ** iface_list = NULL; + // iface_list = (gchar**) dbus_get_all_ip_interface(); + iface_list = (gchar**) dbus_get_all_ip_interface_by_name(); + gchar ** iface = NULL; + + // flag to determine if local_address is found + gboolean iface_found = FALSE; + + gchar *local_iface_addr; + gchar *local_iface_name; + + local_iface_addr= g_malloc(18); + + if (iface_list != NULL) { + + // fill the iterface combo box + for (iface = iface_list; *iface; iface++) { + DEBUG("Interface %s", *iface); + gtk_list_store_append(ipInterfaceListStore, &iter ); + gtk_list_store_set(ipInterfaceListStore, &iter, 0, *iface, -1 ); + + // set the current local address + if (!iface_found && (g_strcmp0(*iface, local_interface) == 0)) { + DEBUG("Setting active local address combo box"); + current_local_iface_iter = iter; + iface_found = TRUE; + } } - - gnome_main_section_new_with_table (_("Network Interface"), &frame, &table, 2, 2); - gtk_container_set_border_width (GTK_CONTAINER(table), 10); - gtk_table_set_row_spacings( GTK_TABLE(table), 5); - - /** - * Retreive the list of IP interface from the - * the daemon and build the combo box. - */ - - GtkListStore * ipInterfaceListStore; - GtkTreeIter iter; - - ipInterfaceListStore = gtk_list_store_new( 1, G_TYPE_STRING ); - label = gtk_label_new_with_mnemonic (_("Local address")); - gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); - - GtkTreeIter current_local_address_iter = iter; - gchar ** iface_list = NULL; - // iface_list = (gchar**) dbus_get_all_ip_interface(); - iface_list = (gchar**) dbus_get_all_ip_interface_by_name(); - gchar ** iface = NULL; - - // flag to determine if local_address is found - gboolean iface_found = FALSE; - - if (iface_list != NULL) { - - // fill the iterface combo box - for (iface = iface_list; *iface; iface++) { - DEBUG("Interface %s", *iface); - gtk_list_store_append(ipInterfaceListStore, &iter ); - gtk_list_store_set(ipInterfaceListStore, &iter, 0, *iface, -1 ); - - // set the current local address - if (!iface_found && (g_strcmp0(*iface, local_interface) == 0)) { - DEBUG("Setting active local address combo box"); - current_local_address_iter = iter; - iface_found = TRUE; - } - } - - if(!iface_found) { - DEBUG("Did not find local ip address, take fisrt in the list"); - gtk_tree_model_get_iter_first(GTK_TREE_MODEL(ipInterfaceListStore), ¤t_local_address_iter); - } - + + if(!iface_found) { + DEBUG("Did not find local ip address, take fisrt in the list"); + gtk_tree_model_get_iter_first(GTK_TREE_MODEL(ipInterfaceListStore), ¤t_local_iface_iter); } - - localAddressCombo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(ipInterfaceListStore)); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), localAddressCombo); - gtk_table_attach ( GTK_TABLE( table ), localAddressCombo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - g_object_unref(G_OBJECT(ipInterfaceListStore)); - - GtkCellRenderer * ipInterfaceCellRenderer; - ipInterfaceCellRenderer = gtk_cell_renderer_text_new(); - gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(localAddressCombo), ipInterfaceCellRenderer, TRUE); - gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(localAddressCombo), ipInterfaceCellRenderer, "text", 0, NULL); - gtk_combo_box_set_active_iter(GTK_COMBO_BOX(localAddressCombo), ¤t_local_address_iter); - - // Local port widget - label = gtk_label_new_with_mnemonic (_("Local port")); - gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); - gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); - localPortSpinBox = gtk_spin_button_new_with_range(1, 65535, 1); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), localPortSpinBox); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(localPortSpinBox), g_ascii_strtod(local_port, NULL)); - - gtk_table_attach_defaults(GTK_TABLE(table), localPortSpinBox, 1, 2, 1, 2); - - return frame; + + } + + + localAddressCombo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(ipInterfaceListStore)); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), localAddressCombo); + gtk_table_attach ( GTK_TABLE( table ), localAddressCombo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + g_object_unref(G_OBJECT(ipInterfaceListStore)); + + + GtkCellRenderer * ipInterfaceCellRenderer; + ipInterfaceCellRenderer = gtk_cell_renderer_text_new(); + + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(localAddressCombo), ipInterfaceCellRenderer, TRUE); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(localAddressCombo), ipInterfaceCellRenderer, "text", 0, NULL); + gtk_combo_box_set_active_iter(GTK_COMBO_BOX(localAddressCombo), ¤t_local_iface_iter); + + + // Fill the text entry with the ip address of local interface selected + localAddressEntry = gtk_entry_new(); + local_iface_name = (gchar *) gtk_combo_box_get_active_text (GTK_COMBO_BOX (localAddressCombo)); + sflphone_get_interface_addr_from_name(local_iface_name, &local_iface_addr); + gtk_entry_set_text(GTK_ENTRY(localAddressEntry), local_iface_addr); + gtk_widget_set_sensitive(localAddressEntry, FALSE); + gtk_table_attach ( GTK_TABLE( table ), localAddressEntry, 2, 3, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + g_free(local_iface_addr); + + // Local port widget + label = gtk_label_new_with_mnemonic (_("Local port")); + gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); + gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); + localPortSpinBox = gtk_spin_button_new_with_range(1, 65535, 1); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), localPortSpinBox); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(localPortSpinBox), g_ascii_strtod(local_port, NULL)); + + gtk_table_attach_defaults(GTK_TABLE(table), localPortSpinBox, 1, 2, 1, 2); + + return frame; } GtkWidget* create_published_address (account_t **a) { diff --git a/sflphone-common/src/audio/audiolayer.cpp b/sflphone-common/src/audio/audiolayer.cpp index e0a84d48481a1514b163a5824840f442517ffdbc..c6b40d81ef122f51b23a125b0f2569fc1e5295b6 100644 --- a/sflphone-common/src/audio/audiolayer.cpp +++ b/sflphone-common/src/audio/audiolayer.cpp @@ -40,7 +40,6 @@ void AudioLayer::flushUrgent (void) int AudioLayer::putUrgent (void* buffer, int toCopy) { - _debug ("------------------- AudioLayer::putUrgent --------------------"); int a; ost::MutexLock guard (_mutex); diff --git a/sflphone-common/src/audio/audiortp/AudioRtpSession.h b/sflphone-common/src/audio/audiortp/AudioRtpSession.h index d168cb8d750fef943960ef2e3b1c7999002a4bc3..7bdfe3c4063692f4cceda3a378fb2fd9961ee9b6 100644 --- a/sflphone-common/src/audio/audiortp/AudioRtpSession.h +++ b/sflphone-common/src/audio/audiortp/AudioRtpSession.h @@ -81,17 +81,17 @@ namespace sfl { void setDestinationIpAddress(void); int processDataEncode(void); - void processDataDecode(unsigned char * spkrData, unsigned int size, int& countTime); + void processDataDecode(unsigned char * spkrData, unsigned int size); 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); + return (int) ( ((float) _converterSamplingRate * codecFrameSize * sizeof(SFLDataFormat))/ 1000.0); } - void sendMicData(int timestamp); - void receiveSpeakerData (int& countTime); + void sendMicData(); + void receiveSpeakerData (); ost::Time * _time; @@ -163,7 +163,20 @@ namespace sfl { */ ManagerImpl * _manager; - int converterSamplingRate; + /** + * Sampling rate of audio converter + */ + int _converterSamplingRate; + + /** + * Timestamp for this session + */ + int _timestamp; + + /** + * Time counter used to trigger incoming call notification + */ + int _countNotificationTime; protected: SIPCall * _ca; @@ -186,6 +199,9 @@ namespace sfl { _codecSampleRate(0), _layerFrameSize(0), _manager(manager), + _converterSamplingRate(0), + _timestamp(0), + _countNotificationTime(0), _ca (sipcall) { setCancel (cancelDefault); @@ -239,7 +255,7 @@ namespace sfl { // may be different than one already setted // converterSamplingRate = _audiolayer->getMainBuffer()->getInternalSamplingRate(); - converterSamplingRate = _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate(); + _converterSamplingRate = _manager->getAudioDriver()->getMainBuffer()->getInternalSamplingRate(); // initialize SampleRate converter using AudioLayer's sampling rate // (internal buffers initialized with maximal sampling rate and frame size) @@ -390,8 +406,7 @@ namespace sfl { } template <typename D> - void AudioRtpSession<D>::processDataDecode(unsigned char * spkrData, unsigned int size, int& countTime) - { + void AudioRtpSession<D>::processDataDecode(unsigned char * spkrData, unsigned int size) { if (_audiocodec != NULL) { @@ -429,26 +444,23 @@ namespace sfl { } // Notify (with a beep) an incoming call when there is already a call - countTime += _time->getSecond(); - if (_manager->incomingCallWaiting() > 0) { - int countTime_modulo = countTime % 4000; - // _debug("countTime: %i\n", countTime); - // _debug("countTime_modulo: %i\n", countTime_modulo); - if ((countTime_modulo - countTime) < 0) { + _countNotificationTime += _time->getSecond(); + int countTimeModulo = _countNotificationTime % 5000; + // _debug("countNotificationTime: %d\n", countNotificationTime); + // _debug("countTimeModulo: %d\n", countTimeModulo); + if ((countTimeModulo - _countNotificationTime) < 0) { _manager->notificationIncomingCall(); } - countTime = countTime_modulo; + _countNotificationTime = countTimeModulo; } - } else { - countTime += _time->getSecond(); - } + } } template <typename D> - void AudioRtpSession<D>::sendMicData(int timestamp) + void AudioRtpSession<D>::sendMicData() { // STEP: // 1. get data from mic @@ -456,7 +468,9 @@ namespace sfl { // 3. encode it // 4. send it - timestamp += _time->getSecond(); + // Increment timestamp for outgoing packet + + _timestamp += _codecFrameSize; if (!_audiolayer) { _debug ("No audiolayer available for MIC\n"); @@ -471,12 +485,12 @@ namespace sfl { int compSize = processDataEncode(); // putData put the data on RTP queue, sendImmediate bypass this queue - static_cast<D*>(this)->putData (timestamp, _micDataEncoded, compSize); + static_cast<D*>(this)->putData (_timestamp, _micDataEncoded, compSize); } template <typename D> - void AudioRtpSession<D>::receiveSpeakerData (int& countTime) + void AudioRtpSession<D>::receiveSpeakerData () { if (!_audiolayer) { _debug ("No audiolayer available for speaker\n"); @@ -501,11 +515,9 @@ namespace sfl { unsigned int size = adu->getSize(); // size in char - // _debug("RTP size: %i\n", size); - - // Size of DTMF over RTP + // DTMF over RTP, size must be over 4 in order to process it as voice data if(size > 4) { - processDataDecode (spkrData, size, countTime); + processDataDecode (spkrData, size); } } @@ -526,10 +538,10 @@ namespace sfl { initBuffers(); + // Timestamp must be initialized randomly + _timestamp = static_cast<D*>(this)->getCurrentTimestamp(); + int sessionWaiting; - int timestep = _codecFrameSize; - int timestamp = static_cast<D*>(this)->getCurrentTimestamp(); // for mic - int countTime = 0; // for receive int threadSleep = 0; if (_codecSampleRate != 0) @@ -551,9 +563,6 @@ namespace sfl { _manager->getAudioDriver()->startStream(); static_cast<D*>(this)->startRunning(); - // Already called in _audiolayer->startStream() - // _audiolayer->flushUrgent(); - // _audiolayer->flushMain(); _debug ("Entering RTP mainloop for callid %s\n",_ca->getCallId().c_str()); @@ -569,11 +578,10 @@ namespace sfl { // Send session sessionWaiting = static_cast<D*>(this)->isWaiting(); - sendMicData (timestamp); - timestamp += timestep; + sendMicData (); // Recv session - receiveSpeakerData (countTime); + receiveSpeakerData (); // Let's wait for the next transmit cycle if (sessionWaiting == 1) { @@ -589,8 +597,6 @@ namespace sfl { // Let's wait for the next transmit cycle Thread::sleep (TimerPort::getTimer()); - - // TimerPort::incTimer(20); // 'frameSize' ms TimerPort::incTimer (threadSleep); } diff --git a/sflphone-common/src/dbus/callmanager-introspec.xml b/sflphone-common/src/dbus/callmanager-introspec.xml index 83e5009c97a16f584f09f7ec1896e585fc8d2f37..34f4eab3ec6cf7f05cd51faf845a0c64313654dd 100644 --- a/sflphone-common/src/dbus/callmanager-introspec.xml +++ b/sflphone-common/src/dbus/callmanager-introspec.xml @@ -1,11 +1,49 @@ -<?xml version="1.0" ?> +<?xml version="1.0" encoding="UTF-8" ?> <node name="/org/sflphone/SFLphone"> + + <!--* The CallManager interface is used to manage any call related + actions. + + Since SFLphone-daemon support multiple incoming/outgoing + calls, any actions involving a specific call must address the + method by the means of a unique callID. SFLphone-clients is + responsible to generate the callID on outgoing call. On the + otehr hand, SFLphone-daemon will generate a unique callID on + incoming calls. + + Actions are performed asynchronously, SFLphone-client should + subscribe to the callStateChanged signal in order to be + notified on updates in call status. + --> <interface name="org.sflphone.SFLphone.CallManager"> - + <method name="placeCall"> - <arg type="s" name="accountID" direction="in"/> - <arg type="s" name="callID" direction="in"/> - <arg type="s" name="to" direction="in"/> + <!--* This is the main method in order to place a new call. The + call is registered to the daemon using this method + specified a unique identifier and VoIP Accout to be bound with. + + The account is specified by its accountID. + + If the call is to be placed whithout any account by the + means of a SIP URI (i.e. sip:num@server), the + "IP2IP_PROFILE" is passed as the accountID. For more + details about accounts see the configuration manager interface. + + The callID is a unique identifier that must be randomly + generated on sflphone-client's side. Any subsequent + actions refering to this call must use this callID. + + If bound to a VoIP account, the to argument is the phone + number. In case of calls involving "IP2IP_PROFILE", a + complete SIP URI must be specified. + + @param[in] input accountID + @param[in] input callID + @param[in] input to + --> + <arg type="s" name="accountID" direction="in" /> + <arg type="s" name="callID" direction="in" /> + <arg type="s" name="to" direction="in" /> </method> <method name="placeCallFirstAccount"> @@ -14,84 +52,186 @@ </method> <method name="refuse"> + <!--* Method called to refuse an incoming call. + + @param[in] input callID + --> <arg type="s" name="callID" direction="in"/> </method> <method name="accept"> + <!--* Method called to answer an incoming call. Automatically put + the current call on state HOLD. + + @param[in] input callID + --> <arg type="s" name="callID" direction="in"/> </method> <method name="hangUp"> + <!--* Method called to hangup a call in state "CURRENT" or "HOLD". + + @param[in] input callID + --> <arg type="s" name="callID" direction="in"/> </method> <method name="hangUpConference"> + <!--* This method will hangup a conference in state "" + every call participating to the conference. + + @param[in] input confID + --> <arg type="s" name="confID" direction="in"/> </method> <method name="hold"> + <!--* Place this call on state HOLD. + + @param[in] input confID + --> <arg type="s" name="callID" direction="in"/> </method> <method name="unhold"> + <!--* Place this call on state CURRENT. + + @param[in] input confID + --> <arg type="s" name="callID" direction="in"/> </method> <method name="transfert"> + <!--* Transfer a call to given phone number. + + @param[in] input confID + @param[in] input to + --> <arg type="s" name="callID" direction="in"/> <arg type="s" name="to" direction="in"/> </method> <method name="playDTMF"> + <!--* Dual-Tone multi-frequency. Tell SFLphone-daemon to play + dial tones. A SIP INFO message is sent to notify the server. + + @param[in] input Unicode charter for pressed key + --> <arg type="s" name="key" direction="in"/> </method> <method name="startTone"> + <!--* This method is used to start audio stream and play tone. + + @param[in] input confID + --> <arg type="i" name="start" direction="in"/> <arg type="i" name="type" direction="in"/> </method> <method name="setVolume"> + <!--* This method sets the volume using a linear scale + [0,100]. Pulseaudio has its own mechanism to modify + application volume. This method is enabled only if the + ALSA API is used. + + @param[in] input device + @param[in] input value + --> <arg type="s" name="device" direction="in"/> <arg type="d" name="value" direction="in"/> </method> <method name="getVolume"> + <!--* This method is enabled only if the ALSA API is used, Pulseaudio + has its own mechanism to modify application volume. Return + a value on a linear scale [0,100]. + + @param[in] input device + @param[out] output value + --> <arg type="s" name="device" direction="in"/> <arg type="d" name="value" direction="out"/> </method> <method name="joinParticipant"> + <!--* Join two participants together to create a 3-way + conference including current SFLphone-client. + conferenceCreated signal is emited on success. + + @param[in] input sel_callID + @param[in] input drag_callID + --> <arg type="s" name="sel_callID" direction="in"/> <arg type="s" name="drag_callID" direction="in"/> </method> <method name="addParticipant"> + <!--* Join a new particiant to an already created conference. + conferenceChaged signal is emited on success. + + @param[in] input callID + @param[in] input confID + --> <arg type="s" name="callID" direction="in"/> <arg type="s" name="confID" direction="in"/> </method> <method name="addMainParticipant"> + <!--* As SFLphone-daemon can handle multiple calls and + conferences. It may happen that SFLphone-client's user + leave a conference to answer an incoming call or + send new ones. This method is used to reintroduce + SFLphone-client's user into the conference. + + It put the current call on state HOLD or detach + SFLphone-client's user from the another conference. + + @param[in] input confID + --> <arg type="s" name="confID" direction="in"/> </method> <method name="detachParticipant"> + <!--* Detach the given call from the conference. If only one + participant is left, the conference is deleted and the + "conferenceRemoved" signal is emited. + + @param[in] input callID + --> <arg type="s" name="callID" direction="in"/> </method> <method name="joinConference"> + <!--* Method used to join two conference together. + + @param[in] input sel_confID + @param[in] input drag_confID + --> <arg type="s" name="sel_confID" direction="in"/> <arg type="s" name="drag_confID" direction="in"/> </method> <method name="getConferenceDetails"> + <!--* Returns a hashtable containing conference details. + + "CONFID" + "CONF_STATE" + + @param[in] input confID + @param[out] output a infos + --> <arg type="s" name="callID" direction="in"/> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/> <arg type="a{ss}" name="infos" direction="out"/> </method> <method name="getConferenceList"> - <arg type="as" name="list" direction="out"/> + <!--* Returns a list containing all active confID in SFLphone-daemon. + + @param[out] output list + --> + <arg type="as" name="list" direction="out"/> </method> <method name="setRecording"> @@ -104,16 +244,36 @@ </method> <method name="getCallDetails"> + <!--* Returns a hashtable containing call details. + + "ACCOUNTID" + "PEER_NUMBER" + "PEER_NAME" + "DISPLAY_NAME" Name to display + "CALL_STATE" The state of the call + "CALL_TYPE" SIP or IAX + + @param[in] input callID + @param[out] output a infos + --> <arg type="s" name="callID" direction="in"/> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/> <arg type="a{ss}" name="infos" direction="out"/> </method> <method name="getCallList"> - <arg type="as" name="list" direction="out"/> + <!--* Returns a list containing all active callID in SFLphone-daemon. + + @param[out] output list + --> + <arg type="as" name="list" direction="out"/> </method> <method name="getCurrentCallID"> + <!--* Returns the CURRENT callID + + @param[out] output callID + --> <arg type="s" name="callID" direction="out"/> </method> @@ -128,6 +288,16 @@ </signal> <signal name="incomingCall"> + <!--* Signal sent to notify incoming calls. + + The callID generated by the daemon and must be stored + by SFLphone-client in order to address other action for + this call. + + @param[in] input accountID + @param[in] input callID + @param[in] input from + --> <arg type="s" name="accountID" /> <arg type="s" name="callID" /> <arg type="s" name="from" /> @@ -139,33 +309,92 @@ </signal> <signal name="callStateChanged"> + <!--* Signal emited by SFLphone-daemon to notify of a chage in + call state. + + The following is a liste of possible call state: + + "INCOMING" Initial state of incoming calls + "RINGING" Initial state of received outgoing call + "CURRENT" The normal active state of an answered call + "HUNGUP" Notify that the call has been hungup by peer + "BUSY" + "FAILURE" Signal emited on failure to answer the call + "HOLD" CAll state is now on hold + "UNHOLD_RECORD" CAll state is now on CURRENT (pursue recording) + "UNHOLD_CURRENT" CAll state is now on CURRENT + + @param[in] input accountID + @param[in] input state + --> <arg type="s" name="callID" direction="out"/> <arg type="s" name="state" direction="out"/> </signal> <signal name="conferenceChanged"> + <!--* Signal emited by SFLphone-daemon to notify of a chage in + conference state. + + The following is a liste of possible conference state: + + "ACTIVE_ATACHED" Conference state is active + "ACTIVE_DETACHED" Conference state is active + "HOLD" Conference is on hold + + @param[in] input accountID + @param[in] input state + --> <arg type="s" name="confID" direction="out"/> <arg type="s" name="state" direction="out"/> </signal> <method name="getParticipantList"> + <!--* Return a vector (or a list) containig the callIP of every + participant to a given conference. SFLphone-client should + keep and update the list of participant. + + @param[in] input accountID + @param[out] output List of callID + --> <arg type="s" name="confID" direction="in"/> <arg type="as" name="list" direction="out"/> </method> <signal name="conferenceCreated"> + <!--* Emited when a new conference is created. SFLphone-client + is reponsible to store the confID and call + getParticipantList to update display. + + param[out] output Newly generated confID + --> <arg type="s" name="confID" direction="out"/> </signal> <signal name="conferenceRemoved"> + <!--* Emited when a new conference is removed. SFLphone-client + should have kept a list of current participant in order to + display modification. + + @param[out] output confID + --> <arg type="s" name="confID" direction="out"/> </signal> <method name="holdConference"> + <!--* Put the hole conference on hold. Every call participating + to this conference will be update to state HOLD. + + @param[in] input confID + --> <arg type="s" name="confID" direction="in"/> </method> <method name="unholdConference"> + <!--* Put the conference on state ACTIVE. Every call participating + to this conference will be updated to state UNHOLD. + + @param[in] input confID + --> <arg type="s" name="confID" direction="in"/> </method> diff --git a/sflphone-common/src/dbus/configurationmanager-introspec.xml b/sflphone-common/src/dbus/configurationmanager-introspec.xml index e7532d16cb2d161e29d042941a59fffd0d49ae1b..944cf9f685ca044a59e91543d4da3fbc7a1d1b8d 100644 --- a/sflphone-common/src/dbus/configurationmanager-introspec.xml +++ b/sflphone-common/src/dbus/configurationmanager-introspec.xml @@ -4,12 +4,78 @@ <!-- Accounts-related methods --> <method name="getAccountDetails"> + <!--* Method that returns a hashtable containing the current + account configuration setting. + + CONFIG_ACCOUNT_ENABLE + CONFIG_ACCOUNT_RESOLVE_ONCE + CONFIG_ACCOUNT_TYPE + HOSTNAME + USERNAME + PASSWORD + REALM + AUTHENTICATION_USERNAME + CONFIG_ACCOUNT_MAILBOX + CONFIG_ACCOUNT_REGISTRATION_EXPIRE + LOCAL_INTERFACE + PUBLISHED_SAMEAS_LOCAL + PUBLISHED_ADDRESS + LOCAL_PORT + PUBLISHED_PORT + DISPLAY_NAME + STUN_ENABLE + STUN_SERVER + + REGISTRATION_STATUS + REGISTRATION_STATE_CODE + REGISTRATION_STATE_DESCRIPTION + SRTP_KEY_EXCHANGE + SRTP_ENABLE + + SRTP_RTP_FALLBACK + ZRTP_DISPLAY_SAS + ZRTP_DISPLAY_SAS_ONCE + ZRTP_HELLO_HASH + ZRTP_NOT_SUPP_WARNING + + TLS_LISTENER_PORT + TLS_ENABLE + TLS_CA_LIST_FILE + TLS_CERTIFICATE_FILE + TLS_PRIVATE_KEY_FILE + + TLS_METHOD + TLS_CIPHERS + TLS_SERVER_NAME + TLS_VERIFY_SERVER + TLS_VERIFY_CLIENT + TLS_REQUIRE_CLIENT_CERTIFICATE + TLS_NEGOTIATION_TIMEOUT_SEC + TLS_NEGOTIATION_TIMEOUT_MSEC + + + @param[in] input accountID + @param[out] output details + --> <arg type="s" name="accountID" direction="in"/> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/> <arg type="a{ss}" name="details" direction="out"/> </method> <method name="setAccountDetails"> + <!--* Modify the current accout parameter settings given an + accountID and a hash table containing the parameters to + update. The hash table is not required to be complete, + only the parameter to change may be specified. Only the + running parameters are updated dynamically, configuration + settings are stored in the configuration file when + SFLphone-daemon quit. + + For a complete list of account settings refer to getAccountDetails + + @param[in] input accountID + @param[in] input details + --> <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="MapStringString"/> <arg type="s" name="accountID" direction="in"/> <arg type="a{ss}" name="details" direction="in"/> @@ -26,15 +92,59 @@ <arg type="i" name="number" direction="in"/> </method> - <method name="deleteAllCredential"> - <arg type="s" name="accountID" direction="in"/> + <method name="deleteAllCredential"> + <arg type="s" name="accountID" direction="in"/> </method> <method name="getIp2IpDetails"> + <!--* Specific call to get configuration settings of the + IP2IP_PROFILE. Which are sligthly different since no VoIP + Account parameters are envolved. + + ACCOUNT_ID + SRTP_KEY_EXCHANGE + SRTP_ENABLE + SRTP_RTP_FALLBACK + ZRTP_DISPLAY_SAS + ZRTP_HELLO_HASH + ZRTP_NOT_SUPP_WARNING + ZRTP_DISPLAY_SAS_ONCE + LOCAL_INTERFACE + LOCAL_PORT + + TLS_LISTENER_PORT + TLS_CA_LIST_FILE + TLS_CERTIFICATE_FILE + TLS_PRIVATE_KEY_FILE + TLS_PASSWORD + TLS_METHOD + TLS_CIPHERS + TLS_SERVER_NAME + TLS_VERIFY_SERVER + TLS_VERIFY_CLIENT + TLS_REQUIRE_CLIENT_CERTIFICATE + TLS_NEGOTIATION_TIMEOUT_SEC + TLS_NEGOTIATION_TIMEOUT_MSEC + + @param[in] input accountID + @param[out] output details + --> <arg type="a{ss}" name="details" direction="out"/> </method> <method name="setIp2IpDetails"> + <!--* Modify the IP2IP_PROFILE parameter settings a hash table + containing the parameters to update. The hash table is not required to be complete, + only the parameters to be modified may be specified. Also, + only the running configuration is updated dynamically, + settings are stored in the configuration file when + SFLphone-daemon quit. + + For a complete list of account settings refer to getAccountDetails + + @param[in] input accountID + @param[in] input details + --> <arg type="a{ss}" name="details" direction="in"/> </method> @@ -50,25 +160,50 @@ </method> <method name="addAccount"> + <!--* Add a new account to the SFLphone-daemon list. If no + details are specified, default parameters are used. + + @param[in] input details + @param[out] output accountID + --> <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="MapStringString"/> <arg type="a{ss}" name="details" direction="in"/> <arg type="s" name="createdAccountId" direction="out"/> </method> <method name="setAccountsOrder"> + <!--* Update the account list given a new list of accountID. If no account is specified + for a call, the first one in the list will be used. + + @param[in] input order + --> <arg type="s" name="order" direction="in"/> </method> <method name="removeAccount"> + <!--* Delete an account from SFLphone-daemon list and erase + account parameters from configuration file. + + @param[in] input accountID + --> <arg type="s" name="accoundID" direction="in"/> </method> <method name="getAccountList"> + <!--* Get teh accountlist as stored in SFLphone-daemon. + + @param[in] input accountID + --> <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/> <arg type="as" name="list" direction="out"/> </method> <method name="sendRegister"> + <!--* Send accout registration request to PBX server. Register + the account if expire=1, unregister if expire=0. + + @param[in] input accountID + --> <arg type="s" name="accountID" direction="in"/> <arg type="i" name="expire" direction="in"/> </method> diff --git a/sflphone-common/src/sip/sipvoiplink.cpp b/sflphone-common/src/sip/sipvoiplink.cpp index 9b2a1e510a349d72623e19ab983274e87ea02abf..b79f05197c11a08df129821077d79cbc61fde147 100644 --- a/sflphone-common/src/sip/sipvoiplink.cpp +++ b/sflphone-common/src/sip/sipvoiplink.cpp @@ -395,8 +395,6 @@ std::string SIPVoIPLink::getInterfaceAddrFromName(std::string ifaceName) { if((err = ioctl(fd, SIOCGIFADDR, &ifr)) < 0) _debug("getInterfaceAddrFromName use default interface (0.0.0.0)\n"); - - // printf("Local address: %s\n", inet_ntos( ((struct sockaddr_in *) &ifr.ifr_ifru.ifru_addr)->sin_addr )); saddr_in = (struct sockaddr_in *)&ifr.ifr_addr; addr_in = &(saddr_in->sin_addr); @@ -2611,8 +2609,8 @@ pj_status_t SIPVoIPLink::createTlsTransport(const AccountID& accountID, std::str // Update TLS settings for account registration using the default listeners // Pjsip does not allow to create multiple listener - pjsip_tpmgr *mgr = pjsip_endpt_get_tpmgr(_endpt); - pjsip_tls_listener_update_settings(_endpt, _pool, mgr, _localTlsListener, account->getTlsSetting()); + // pjsip_tpmgr *mgr = pjsip_endpt_get_tpmgr(_endpt); + // pjsip_tls_listener_update_settings(_endpt, _pool, mgr, _localTlsListener, account->getTlsSetting()); // Create a new TLS connection from TLS listener pjsip_transport *tls;