Commit a60d39de authored by Emmanuel Milou's avatar Emmanuel Milou
Browse files

Merge branch 'master' of...

Merge branch 'master' of git+ssh://repos-sflphone-git@git.sflphone.org/var/repos/sflphone/git/sflphone
parents 7234f4c7 a36aa008
...@@ -1101,12 +1101,12 @@ void sflphone_fill_codec_list () { ...@@ -1101,12 +1101,12 @@ void sflphone_fill_codec_list () {
void sflphone_fill_codec_list_per_account (account_t **account) { void sflphone_fill_codec_list_per_account (account_t **account) {
gchar **order; gchar **order;
gchar** details; gchar** details;
gchar** pl; gchar** pl;
gchar *accountID; gchar *accountID;
GQueue *codeclist; GQueue *codeclist;
gboolean active = FALSE; gboolean active = FALSE;
order = (gchar**) dbus_get_active_codec_list ((*account)->accountID); order = (gchar**) dbus_get_active_codec_list ((*account)->accountID);
codeclist = (*account)->codecs; codeclist = (*account)->codecs;
...@@ -1118,7 +1118,7 @@ void sflphone_fill_codec_list_per_account (account_t **account) { ...@@ -1118,7 +1118,7 @@ void sflphone_fill_codec_list_per_account (account_t **account) {
{ {
codec_t * cpy; codec_t * cpy;
// Each account will have a copy of the system-wide capabilities // Each account will have a copy of the system-wide capabilities
codec_create_new_from_caps (codec_list_get_by_payload ((gconstpointer) atoi (*order), NULL), &cpy); codec_create_new_from_caps (codec_list_get_by_payload ((gconstpointer) (size_t)atoi (*order), NULL), &cpy);
if (cpy) { if (cpy) {
cpy->is_active = TRUE; cpy->is_active = TRUE;
codec_list_add (cpy, &codeclist); codec_list_add (cpy, &codeclist);
...@@ -1136,7 +1136,7 @@ void sflphone_fill_codec_list_per_account (account_t **account) { ...@@ -1136,7 +1136,7 @@ void sflphone_fill_codec_list_per_account (account_t **account) {
codec_t * current_cap = capabilities_get_nth (i); codec_t * current_cap = capabilities_get_nth (i);
// Check if this codec has already been enabled for this account // Check if this codec has already been enabled for this account
if (codec_list_get_by_payload ( (gconstpointer) current_cap->_payload, codeclist) == NULL) { if (codec_list_get_by_payload ( (gconstpointer) (size_t)(current_cap->_payload), codeclist) == NULL) {
// codec_t *cpy; // codec_t *cpy;
// codec_create_new_from_caps (current_cap, &cpy); // codec_create_new_from_caps (current_cap, &cpy);
current_cap->is_active = active; current_cap->is_active = active;
......
...@@ -116,12 +116,16 @@ void change_protocol_cb (account_t *currentAccount UNUSED) { ...@@ -116,12 +116,16 @@ void change_protocol_cb (account_t *currentAccount UNUSED) {
gchar *protocol = gtk_combo_box_get_active_text (GTK_COMBO_BOX (protocolComboBox)); gchar *protocol = gtk_combo_box_get_active_text (GTK_COMBO_BOX (protocolComboBox));
if (g_strcasecmp (protocol, "IAX") == 0) { // Only if tabs are not NULL
gtk_widget_hide (security_tab); if(security_tab && advanced_tab) {
gtk_widget_hide (advanced_tab);
} else { if (g_strcasecmp (protocol, "IAX") == 0) {
gtk_widget_show (security_tab); gtk_widget_hide (GTK_WIDGET(security_tab));
gtk_widget_show (advanced_tab); gtk_widget_hide (GTK_WIDGET(advanced_tab));
} else {
gtk_widget_show (GTK_WIDGET(security_tab));
gtk_widget_show (GTK_WIDGET(advanced_tab));
}
} }
} }
...@@ -548,6 +552,7 @@ static void key_exchange_changed_cb(GtkWidget *widget, gpointer data) ...@@ -548,6 +552,7 @@ static void key_exchange_changed_cb(GtkWidget *widget, gpointer data)
static void use_sip_tls_cb(GtkWidget *widget, gpointer data) static void use_sip_tls_cb(GtkWidget *widget, gpointer data)
{ {
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
DEBUG("Using sips"); DEBUG("Using sips");
gtk_widget_set_sensitive(GTK_WIDGET(data), TRUE); gtk_widget_set_sensitive(GTK_WIDGET(data), TRUE);
...@@ -616,7 +621,6 @@ static local_interface_changed_cb(GtkWidget * widget, gpointer data UNUSED) { ...@@ -616,7 +621,6 @@ static local_interface_changed_cb(GtkWidget * widget, gpointer data UNUSED) {
static set_published_addr_manually_cb(GtkWidget * widget, gpointer data UNUSED) static set_published_addr_manually_cb(GtkWidget * widget, gpointer data UNUSED)
{ {
DEBUG("set_published_addr_manually_cb");
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
DEBUG("Showing manual options"); DEBUG("Showing manual options");
...@@ -645,7 +649,7 @@ static use_stun_cb(GtkWidget *widget, gpointer data UNUSED) ...@@ -645,7 +649,7 @@ static use_stun_cb(GtkWidget *widget, gpointer data UNUSED)
gtk_widget_show (stunServerEntry); gtk_widget_show (stunServerEntry);
gtk_widget_set_sensitive (sameAsLocalRadioButton, FALSE); gtk_widget_set_sensitive (sameAsLocalRadioButton, FALSE);
gtk_widget_set_sensitive (publishedAddrRadioButton, FALSE); gtk_widget_set_sensitive (publishedAddrRadioButton, FALSE);
DEBUG("Problem occurs here");
gtk_widget_hide (publishedAddressLabel); gtk_widget_hide (publishedAddressLabel);
gtk_widget_hide (publishedPortLabel); gtk_widget_hide (publishedPortLabel);
gtk_widget_hide (publishedAddressEntry); gtk_widget_hide (publishedAddressEntry);
...@@ -658,7 +662,7 @@ static use_stun_cb(GtkWidget *widget, gpointer data UNUSED) ...@@ -658,7 +662,7 @@ static use_stun_cb(GtkWidget *widget, gpointer data UNUSED)
gtk_widget_set_sensitive (sameAsLocalRadioButton, TRUE); gtk_widget_set_sensitive (sameAsLocalRadioButton, TRUE);
gtk_widget_set_sensitive (publishedAddrRadioButton, TRUE); gtk_widget_set_sensitive (publishedAddrRadioButton, TRUE);
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sameAsLocalRadioButton))) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (publishedAddrRadioButton))) {
gtk_widget_show (publishedAddressLabel); gtk_widget_show (publishedAddressLabel);
gtk_widget_show (publishedPortLabel); gtk_widget_show (publishedPortLabel);
gtk_widget_show (publishedAddressEntry); gtk_widget_show (publishedAddressEntry);
...@@ -678,6 +682,7 @@ static use_stun_cb(GtkWidget *widget, gpointer data UNUSED) ...@@ -678,6 +682,7 @@ static use_stun_cb(GtkWidget *widget, gpointer data UNUSED)
static same_as_local_cb(GtkWidget * widget, gpointer data UNUSED) static same_as_local_cb(GtkWidget * widget, gpointer data UNUSED)
{ {
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
DEBUG("Same as local"); DEBUG("Same as local");
gchar * local_interface; gchar * local_interface;
...@@ -692,6 +697,7 @@ static same_as_local_cb(GtkWidget * widget, gpointer data UNUSED) ...@@ -692,6 +697,7 @@ static same_as_local_cb(GtkWidget * widget, gpointer data UNUSED)
gchar * local_port = (gchar *) gtk_entry_get_text(GTK_ENTRY(localPortSpinBox)); 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)); gtk_spin_button_set_value(GTK_SPIN_BUTTON(publishedPortSpinBox), g_ascii_strtod(local_port, NULL));
} }
} }
...@@ -1082,7 +1088,9 @@ GtkWidget* create_published_address (account_t **a) { ...@@ -1082,7 +1088,9 @@ GtkWidget* create_published_address (account_t **a) {
if (g_strcasecmp (published_sameas_local, "true") == 0) { if (g_strcasecmp (published_sameas_local, "true") == 0) {
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sameAsLocalRadioButton), TRUE); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sameAsLocalRadioButton), TRUE);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (publishedAddrRadioButton), FALSE);
} else { } else {
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sameAsLocalRadioButton), FALSE);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (publishedAddrRadioButton), TRUE); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (publishedAddrRadioButton), TRUE);
} }
...@@ -1115,6 +1123,8 @@ GtkWidget* create_published_address (account_t **a) { ...@@ -1115,6 +1123,8 @@ GtkWidget* create_published_address (account_t **a) {
g_signal_connect(sameAsLocalRadioButton, "toggled", G_CALLBACK(same_as_local_cb), sameAsLocalRadioButton); g_signal_connect(sameAsLocalRadioButton, "toggled", G_CALLBACK(same_as_local_cb), sameAsLocalRadioButton);
g_signal_connect(publishedAddrRadioButton, "toggled", G_CALLBACK(set_published_addr_manually_cb), publishedAddrRadioButton); g_signal_connect(publishedAddrRadioButton, "toggled", G_CALLBACK(set_published_addr_manually_cb), publishedAddrRadioButton);
set_published_addr_manually_cb(publishedAddrRadioButton, NULL);
return frame; return frame;
} }
...@@ -1137,6 +1147,7 @@ GtkWidget* create_advanced_tab (account_t **a) { ...@@ -1137,6 +1147,7 @@ GtkWidget* create_advanced_tab (account_t **a) {
gtk_box_pack_start (GTK_BOX (ret), frame, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (ret), frame, FALSE, FALSE, 0);
gtk_widget_show_all (ret); gtk_widget_show_all (ret);
return ret; return ret;
} }
...@@ -1231,9 +1242,10 @@ void show_account_window (account_t * a) { ...@@ -1231,9 +1242,10 @@ void show_account_window (account_t * a) {
/* General Settings */ /* General Settings */
tab = create_basic_tab(&currentAccount); tab = create_basic_tab(&currentAccount);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), tab, gtk_label_new(_("Basic"))); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), tab, gtk_label_new(_("Basic")));
gtk_notebook_page_num(GTK_NOTEBOOK(notebook), tab); gtk_notebook_page_num(GTK_NOTEBOOK(notebook), tab);
g_signal_emit_by_name (protocolComboBox, "changed", NULL); g_signal_emit_by_name ((gpointer)protocolComboBox, "changed", NULL);
} }
...@@ -1415,7 +1427,7 @@ void show_account_window (account_t * a) { ...@@ -1415,7 +1427,7 @@ void show_account_window (account_t * a) {
codec_list_update_to_daemon (currentAccount); codec_list_update_to_daemon (currentAccount);
} }
else { else {
g_print ("IP to IP call\n"); DEBUG("IP to IP call\n");
// Direct IP calls config // Direct IP calls config
// dbus_set_ip2ip_details (directIpCallsProperties); // dbus_set_ip2ip_details (directIpCallsProperties);
} }
......
...@@ -32,7 +32,7 @@ void ...@@ -32,7 +32,7 @@ void
addressbook_search(GtkEntry* entry) addressbook_search(GtkEntry* entry)
{ {
gchar* query = gtk_entry_get_text(GTK_ENTRY (entry)); const gchar* query = gtk_entry_get_text(GTK_ENTRY (entry));
if (strlen(query) >= 3) { if (strlen(query) >= 3) {
AddressBook_Config *addressbook_config; AddressBook_Config *addressbook_config;
......
...@@ -2605,7 +2605,7 @@ void dbus_enable_status_icon (const gchar *value) { ...@@ -2605,7 +2605,7 @@ void dbus_enable_status_icon (const gchar *value) {
gchar* dbus_is_status_icon_enabled (void) { gchar* dbus_is_status_icon_enabled (void) {
GError *error = NULL; GError *error = NULL;
gchar* value = TRUE; gchar *value = NULL;
org_sflphone_SFLphone_ConfigurationManager_is_status_icon_enabled (configurationManagerProxy, &value, &error); org_sflphone_SFLphone_ConfigurationManager_is_status_icon_enabled (configurationManagerProxy, &value, &error);
......
...@@ -105,15 +105,10 @@ main_window_ask_quit () ...@@ -105,15 +105,10 @@ main_window_ask_quit ()
response = gtk_dialog_run (GTK_DIALOG (dialog)); response = gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog); gtk_widget_destroy (dialog);
if (response == GTK_RESPONSE_YES)
{ return (response == GTK_RESPONSE_NO)? FALSE : TRUE ;
return TRUE;
}
else if (response == GTK_RESPONSE_NO)
{
return FALSE;
}
return TRUE;
} }
static gboolean static gboolean
......
...@@ -182,13 +182,17 @@ statusicon_set_tooltip() ...@@ -182,13 +182,17 @@ statusicon_set_tooltip()
int count; int count;
gchar *tip; gchar *tip;
// Add a tooltip to the system tray icon if(status) {
count = account_list_get_registered_accounts();
tip = g_markup_printf_escaped("%s - %s", _("SFLphone"), // Add a tooltip to the system tray icon
g_markup_printf_escaped( count = account_list_get_registered_accounts();
n_("%i active account", "%i active accounts", count), count)); tip = g_markup_printf_escaped("%s - %s", _("SFLphone"),
gtk_status_icon_set_tooltip(status, tip); g_markup_printf_escaped(n_("%i active account", "%i active accounts", count), count));
g_free(tip); gtk_status_icon_set_tooltip(status, tip);
g_free(tip);
}
} }
void void
......
...@@ -362,11 +362,10 @@ help_contents_cb(GtkAction *action) ...@@ -362,11 +362,10 @@ help_contents_cb(GtkAction *action)
GError *error = NULL; GError *error = NULL;
gnome_help_display("sflphone.xml", NULL, &error); gnome_help_display("sflphone.xml", NULL, &error);
if (error != NULL) if (error != NULL) {
{
g_warning("%s", error->message); g_warning("%s", error->message);
g_error_free(error); g_error_free(error);
} }
} }
static void static void
......
...@@ -104,7 +104,19 @@ typedef enum pj_dns_srv_option ...@@ -104,7 +104,19 @@ typedef enum pj_dns_srv_option
* this option is not specified, the SRV resolver will query * this option is not specified, the SRV resolver will query
* the DNS A record for the target instead. * the DNS A record for the target instead.
*/ */
PJ_DNS_SRV_RESOLVE_AAAA = 4 PJ_DNS_SRV_RESOLVE_AAAA = 4,
/**
* Specify if the resolver should fallback to getaddrinfo
* under IPV4 mode if DNS A fails after DNS SRV.
*/
PJ_DNS_SRV_FALLBACK_GETADDRINFO_IPV4 = 8,
/**
* Specify if the resolver should fallback to getaddrinfo
* under IPV6 mode if DNS A fails after DNS SRV.
*/
PJ_DNS_SRV_FALLBACK_GETADDRINFO_IPV6 = 16,
} pj_dns_srv_option; } pj_dns_srv_option;
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
*/ */
#include <pjlib-util/srv_resolver.h> #include <pjlib-util/srv_resolver.h>
#include <pjlib-util/errno.h> #include <pjlib-util/errno.h>
#include <pj/addr_resolv.h>
#include <pj/array.h> #include <pj/array.h>
#include <pj/assert.h> #include <pj/assert.h>
#include <pj/log.h> #include <pj/log.h>
...@@ -583,13 +584,53 @@ static void dns_callback(void *user_data, ...@@ -583,13 +584,53 @@ static void dns_callback(void *user_data,
} else if (status != PJ_SUCCESS) { } else if (status != PJ_SUCCESS) {
char errmsg[PJ_ERR_MSG_SIZE]; char errmsg[PJ_ERR_MSG_SIZE];
/* Update last error */ if ((query_job->option &
query_job->last_error = status; (PJ_DNS_SRV_FALLBACK_GETADDRINFO_IPV4 | PJ_DNS_SRV_FALLBACK_GETADDRINFO_IPV6)))
{
/* Log error */ pj_strerror(status, errmsg, sizeof(errmsg));
pj_strerror(status, errmsg, sizeof(errmsg)); PJ_LOG(4,(query_job->objname,
PJ_LOG(4,(query_job->objname, "DNS A record resolution failed: %s", "DNS A record resolution failed: %s,"
errmsg)); " trying getaddrinfo()",
errmsg));
pj_addrinfo ai;
unsigned count;
int af;
if ((query_job->option & PJ_DNS_SRV_FALLBACK_GETADDRINFO_IPV6)) {
af = pj_AF_INET6();
} else {
af = pj_AF_INET();
}
count = 1;
status = pj_getaddrinfo(af, &query_job->domain_part, &count, &ai);
if (status != PJ_SUCCESS) {
query_job->last_error = status;
pj_strerror(status, errmsg, sizeof(errmsg));
PJ_LOG(4,(query_job->objname, "DNS resolution failed with getaddrinfo(): %s",
errmsg));
} else {
if (srv->addr_cnt < ADDR_MAX_COUNT) {
srv->addr[srv->addr_cnt++].s_addr = ai.ai_addr.ipv4.sin_addr.s_addr;
}
PJ_LOG(5,(query_job->objname,
"DNS getaddrinfo() for %.*s: %s",
(int)srv->target_name.slen,
srv->target_name.ptr,
pj_inet_ntoa(srv->addr[srv->addr_cnt])));
}
} else {
/* Update last error */
query_job->last_error = status;
/* Log error */
pj_strerror(status, errmsg, sizeof(errmsg));
PJ_LOG(4,(query_job->objname, "DNS A record resolution failed: %s",
errmsg));
}
} }
++query_job->host_resolved; ++query_job->host_resolved;
......
...@@ -369,14 +369,21 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver, ...@@ -369,14 +369,21 @@ PJ_DEF(void) pjsip_resolve( pjsip_resolver_t *resolver,
if (query->query_type == PJ_DNS_TYPE_SRV) { if (query->query_type == PJ_DNS_TYPE_SRV) {
status = pj_dns_srv_resolve(&query->naptr[0].name, unsigned option = PJ_TRUE;
&query->naptr[0].res_type, if (type & PJSIP_TRANSPORT_IPV6) {
query->req.def_port, pool, resolver->res, option |= PJ_DNS_SRV_FALLBACK_GETADDRINFO_IPV6;
PJ_TRUE, query, &srv_resolver_cb, NULL); } else {
option |= PJ_DNS_SRV_FALLBACK_GETADDRINFO_IPV4;
}
status = pj_dns_srv_resolve(&query->naptr[0].name,
&query->naptr[0].res_type,
query->req.def_port, pool, resolver->res,
option, query, &srv_resolver_cb, NULL);
} else if (query->query_type == PJ_DNS_TYPE_A) { } else if (query->query_type == PJ_DNS_TYPE_A) {
status = pj_dns_resolver_start_query(resolver->res, status = pj_dns_resolver_start_query(resolver->res,
&query->naptr[0].name, &query->naptr[0].name,
PJ_DNS_TYPE_A, 0, PJ_DNS_TYPE_A, 0,
&dns_a_callback, &dns_a_callback,
......
...@@ -560,11 +560,8 @@ int SIPVoIPLink::sendRegister (AccountID id) ...@@ -560,11 +560,8 @@ int SIPVoIPLink::sendRegister (AccountID id)
// Creates URI // Creates URI
std::string fromUri; std::string fromUri;
std::string contactUri; std::string contactUri;
std::string srvUri; std::string srvUri;
std::string address; std::string address;
fromUri = account->getFromUri(); fromUri = account->getFromUri();
...@@ -1772,7 +1769,7 @@ bool get_dns_server_addresses (std::vector<std::string> *servers) ...@@ -1772,7 +1769,7 @@ bool get_dns_server_addresses (std::vector<std::string> *servers)
// Read configuration files // Read configuration files
if (res_init () != 0) { if (res_init () != 0) {
_debug ("Resolver initialization failed"); _debug ("UserAgent: Resolver initialization failed");
return false; return false;
} }
...@@ -1797,44 +1794,43 @@ pj_status_t SIPVoIPLink::enable_dns_srv_resolver (pjsip_endpoint *endpt, pj_dns_ ...@@ -1797,44 +1794,43 @@ pj_status_t SIPVoIPLink::enable_dns_srv_resolver (pjsip_endpoint *endpt, pj_dns_
std::vector <std::string> dns_servers; std::vector <std::string> dns_servers;
int scount, i; int scount, i;
_debug("UserAgent: Enable DNS SRV resolver");
// Create the DNS resolver instance // Create the DNS resolver instance
status = pjsip_endpt_create_resolver (endpt, &resv); status = pjsip_endpt_create_resolver (endpt, &resv);
if (status != PJ_SUCCESS) { if (status != PJ_SUCCESS) {
_debug ("Error creating the DNS resolver instance"); _error ("UserAgent: Error: Creating the DNS resolver instance");
return status; return status;
} }
if (!get_dns_server_addresses (&dns_servers)) { if (!get_dns_server_addresses (&dns_servers)) {
_debug ("Error while fetching DNS information"); _error ("UserAgent: Error: while fetching DNS information");
return -1; return -1;
} }
// Build the nameservers list needed by pjsip // Build the nameservers list needed by pjsip
if ( (scount = dns_servers.size ()) <= 0) { if ( (scount = dns_servers.size ()) <= 0) {
_debug ("No server detected while fetching DNS information, stop dns resolution"); _warn ("UserAgent: No server detected while fetching DNS information, stop dns resolution");
return 0; return 0;
} }
pj_str_t nameservers[scount]; pj_str_t nameservers[scount];
for (i = 0; i<scount; i++) { for (i = 0; i<scount; i++) {
nameservers[i] = pj_str ( (char*) dns_servers[i].c_str()); _debug("UserAgent: Server: %s", (char *)dns_servers[i].c_str());
nameservers[i] = pj_str ( (char *) dns_servers[i].c_str());
} }
// Update the name servers for the DNS resolver // Update the name servers for the DNS resolver
status = pj_dns_resolver_set_ns (resv, scount, nameservers, NULL); status = pj_dns_resolver_set_ns (resv, scount, nameservers, NULL);
if (status != PJ_SUCCESS) { if (status != PJ_SUCCESS) {
_debug ("Error updating the name servers for the DNS resolver"); _debug ("UserAgent: Error updating the name servers for the DNS resolver");
return status; return status;
} }
// Set the DNS resolver instance of the SIP resolver engine // Set the DNS resolver instance of the SIP resolver engine
status = pjsip_endpt_set_resolver (endpt, resv); status = pjsip_endpt_set_resolver (endpt, resv);
if (status != PJ_SUCCESS) { if (status != PJ_SUCCESS) {
_debug ("Error setting the DNS resolver instance of the SIP resolver engine"); _debug ("UserAgent: Error setting the DNS resolver instance of the SIP resolver engine");
return status; return status;
} }
......
...@@ -135,10 +135,13 @@ class SflPhoneTests(): ...@@ -135,10 +135,13 @@ class SflPhoneTests():
# Start Glib mainloop # Start Glib mainloop
self.sflphone.start() self.sflphone.start()
# SCENARIO 1 Test 4 # SCENARIO 1 Test 4
def test_ip2ip_recv_peer_hungup(self):