diff --git a/sflphone-client-gnome/src/actions.c b/sflphone-client-gnome/src/actions.c index bcf56f7ca3e19f0ee77bef9b0fbf33be25d68d86..35aeb1a761328b7252ee78effcd6a98d808c73c9 100644 --- a/sflphone-client-gnome/src/actions.c +++ b/sflphone-client-gnome/src/actions.c @@ -1098,7 +1098,7 @@ sflphone_srtp_off( callable_obj_t * c ) void sflphone_srtp_show_sas( callable_obj_t * c, const gchar* sas, const gboolean verified) { - if(c==NULL) { + if(c == NULL) { DEBUG("Panic callable obj is NULL in %s at %d", __FILE__, __LINE__); } c->_sas = g_strdup(sas); @@ -1141,3 +1141,20 @@ sflphone_confirm_go_clear( callable_obj_t * c ) main_window_confirm_go_clear(c); } + + void +sflphone_call_state_changed( callable_obj_t * c, const gchar * description, const guint code) +{ + DEBUG("sflphone_call_state_changed"); + if(c == NULL) { + DEBUG("Panic callable obj is NULL in %s at %d", __FILE__, __LINE__); + } else { + //g_free(c->_state_code_description); + //DEBUG("sflphone_call_state_changed"); + c->_state_code_description = g_strdup(description); + c->_state_code = code; + } + + calltree_update_call(current_calls, c); + update_menus(); +} diff --git a/sflphone-client-gnome/src/actions.h b/sflphone-client-gnome/src/actions.h index b96a2aed962e683eed04136ae1f34a875114a96d..f201c248ef9814d78f6819e3af6a3be539ecaaa3 100644 --- a/sflphone-client-gnome/src/actions.h +++ b/sflphone-client-gnome/src/actions.h @@ -232,5 +232,15 @@ void sflphone_confirm_go_clear( callable_obj_t * c ); */ void sflphone_request_go_clear(void); +/** + * Called when the UI needs to be refreshed to + * better inform the user about the current + * state of the call. + * @param c A pointer to the call that needs to be updated + * @param description A textual description of the code + * @param code The status code as in SIP or IAX + */ + +void sflphone_call_state_changed(callable_obj_t * c, const gchar * description, const guint code); #endif diff --git a/sflphone-client-gnome/src/callable_obj.c b/sflphone-client-gnome/src/callable_obj.c index a50b631cbdbe8f08fe09677cfc9001f230a0e012..4ea86bc699539254b05b435f48df7f1126ebb203 100644 --- a/sflphone-client-gnome/src/callable_obj.c +++ b/sflphone-client-gnome/src/callable_obj.c @@ -94,10 +94,12 @@ void create_new_call (callable_type_t type, call_state_t state, gchar* callID , obj = g_new0 (callable_obj_t, 1); obj->_error_dialogs = g_ptr_array_new(); - + // Set fields obj->_type = type; obj->_state = state; + obj->_state_code = 0; + obj->_state_code_description = ""; obj->_accountID = g_strdup (accountID); obj->_peer_name = g_strdup (peer_name); obj->_peer_number = g_strdup (peer_number); diff --git a/sflphone-client-gnome/src/callable_obj.h b/sflphone-client-gnome/src/callable_obj.h index 6dc95285d00d0d6e320c4e39098bcbc27351c084..75e59232b8fa03980cc2728a407a4d4308f54112 100644 --- a/sflphone-client-gnome/src/callable_obj.h +++ b/sflphone-client-gnome/src/callable_obj.h @@ -91,12 +91,14 @@ typedef enum typedef struct { callable_type_t _type; // CALL - HISTORY ENTRY - CONTACT - call_state_t _state; // The state of the call + call_state_t _state; // The state of the call + int _state_code; // The numeric state code as defined in SIP or IAX + gchar* _state_code_description; // A textual description of _state_code gchar* _callID; // The call ID gchar* _accountID; // The account the call is made with - time_t _time_start; // The timestamp the call was initiating + time_t _time_start; // The timestamp the call was initiating time_t _time_stop; // The timestamp the call was over - history_state_t _history_state; // The history state if necessary + 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 gchar* _sas; // The Short Authentication String that should be displayed diff --git a/sflphone-client-gnome/src/contacts/calltree.c b/sflphone-client-gnome/src/contacts/calltree.c index 37dbbda7b19262f19997b15c9f8db8364017166e..655655c406b66627757caba64b3c3bff677a6272 100644 --- a/sflphone-client-gnome/src/contacts/calltree.c +++ b/sflphone-client-gnome/src/contacts/calltree.c @@ -394,167 +394,177 @@ calltree_update_call (calltab_t* tab, callable_obj_t * c) for( i = 0; i < nbChild; i++) { - if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, i)) - { - val.g_type = 0; - gtk_tree_model_get_value (GTK_TREE_MODEL(store), &iter, COLUMN_ACCOUNT_PTR, &val); + if(!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, i)) { + continue; + } + + val.g_type = 0; + gtk_tree_model_get_value (GTK_TREE_MODEL(store), &iter, COLUMN_ACCOUNT_PTR, &val); - iterCall = (callable_obj_t*) g_value_get_pointer(&val); - g_value_unset(&val); + iterCall = (callable_obj_t*) g_value_get_pointer(&val); + g_value_unset(&val); - if(iterCall == c) - { - // Existing call in the list - gchar * description; - gchar * date=""; - gchar * duration=""; - - if(c->_state == CALL_STATE_TRANSFERT) - { - description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>\n<i>Transfert to:%s</i> ", - c->_peer_number, - c->_peer_name, - c->_trsft_to - ); - } - else - { - - // c->_zrtp_confirmed == FALSE : Hack explained in callable_obj.h - if((c->_sas != NULL) && (display_sas == TRUE) && (c->_srtp_state == SRTP_STATE_SAS_UNCONFIRMED) && (c->_zrtp_confirmed == FALSE)) { - description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>\n<i>Confirm SAS <b>%s</b> ?</i> ", - c->_peer_number, - c->_peer_name, - c->_sas - ); - } else { - description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>", - c->_peer_number, - c->_peer_name ); - } + if(iterCall != c) { + continue; + } + + /* Update text */ + gchar * description; + gchar * date=""; + gchar * duration=""; + + if(c->_state == CALL_STATE_TRANSFERT) + { + description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>\n<i>Transfert to:%s</i> ", + c->_peer_number, + c->_peer_name, + c->_trsft_to + ); + } + else + { + // c->_zrtp_confirmed == FALSE : Hack explained in callable_obj.h + if((c->_sas != NULL) && (display_sas == TRUE) && (c->_srtp_state == SRTP_STATE_SAS_UNCONFIRMED) && (c->_zrtp_confirmed == FALSE)) { + description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>\n<i>Confirm SAS <b>%s</b> ?</i> ", + c->_peer_number, + c->_peer_name, + c->_sas + ); + } else { + DEBUG("Updating state code %d %s", c->_state_code, c->_state_code_description); + if (c->_state_code) { + description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>\n<i>%s (%d)</i>", + c->_peer_number, + c->_peer_name, + c->_state_code_description, + c->_state_code); + } else { + description = g_markup_printf_escaped("<b>%s</b> <i>%s</i>", + c->_peer_number, + c->_peer_name ); } + } + } - - if( tab == current_calls ) - { - switch(c->_state) - { - case CALL_STATE_HOLD: - pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/hold.svg", NULL); - break; - case CALL_STATE_RINGING: - pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/ring.svg", NULL); - break; - case CALL_STATE_CURRENT: - pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/current.svg", NULL); - break; - case CALL_STATE_DIALING: - pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/dial.svg", NULL); - break; - case CALL_STATE_FAILURE: - pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/fail.svg", NULL); - break; - case CALL_STATE_BUSY: - pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/busy.svg", NULL); - break; - case CALL_STATE_TRANSFERT: - pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/transfert.svg", NULL); - break; - case CALL_STATE_RECORD: - pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/rec_call.svg", NULL); - break; - default: - WARN("Update calltree - Should not happen!"); - } - + /* Update icons */ + if( tab == current_calls ) + { + DEBUG("Receiving in state %d", c->_state); + switch(c->_state) + { + case CALL_STATE_HOLD: + pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/hold.svg", NULL); + break; + case CALL_STATE_INCOMING: + case CALL_STATE_RINGING: + pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/ring.svg", NULL); + break; + case CALL_STATE_CURRENT: + pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/current.svg", NULL); + break; + case CALL_STATE_DIALING: + pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/dial.svg", NULL); + break; + case CALL_STATE_FAILURE: + pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/fail.svg", NULL); + break; + case CALL_STATE_BUSY: + pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/busy.svg", NULL); + break; + case CALL_STATE_TRANSFERT: + pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/transfert.svg", NULL); + break; + case CALL_STATE_RECORD: + pixbuf = gdk_pixbuf_new_from_file(ICONS_DIR "/rec_call.svg", NULL); + break; + default: + WARN("Update calltree - Should not happen!"); + } - switch(c->_srtp_state) - { - case SRTP_STATE_SAS_UNCONFIRMED: - DEBUG("Secure is ON"); - pixbuf_security = gdk_pixbuf_new_from_file(ICONS_DIR "/lock_unconfirmed.svg", NULL); - if(c->_sas != NULL) { DEBUG("SAS is ready with value %s", c->_sas); } - break; - case SRTP_STATE_SAS_CONFIRMED: - DEBUG("SAS is confirmed"); - pixbuf_security = gdk_pixbuf_new_from_file(ICONS_DIR "/lock_confirmed.svg", NULL); - break; - case SRTP_STATE_SAS_SIGNED: - DEBUG("Secure is ON with SAS signed and verified"); - pixbuf_security = gdk_pixbuf_new_from_file(ICONS_DIR "/lock_certified.svg", NULL); - break; - case SRTP_STATE_UNLOCKED: - DEBUG("Secure is off calltree %d", c->_state); - if(g_strcasecmp(srtp_enabled,"true") == 0) { - pixbuf_security = gdk_pixbuf_new_from_file(ICONS_DIR "/lock_off.svg", NULL); - } - break; - default: - WARN("Update calltree srtp state #%d- Should not happen!", c->_srtp_state); - if(g_strcasecmp(srtp_enabled,"true") == 0) { - pixbuf_security = gdk_pixbuf_new_from_file(ICONS_DIR "/lock_off.svg", NULL); - } - } - } - else - { - switch(c->_history_state) - { - case OUTGOING: - DEBUG("Outgoing state"); - pixbuf = gdk_pixbuf_new_from_file( ICONS_DIR "/outgoing.svg", NULL); - break; - case INCOMING: - DEBUG("Incoming state"); - pixbuf = gdk_pixbuf_new_from_file( ICONS_DIR "/incoming.svg", NULL); - break; - case MISSED: - DEBUG("Missed state"); - pixbuf = gdk_pixbuf_new_from_file( ICONS_DIR "/missed.svg", NULL); - break; - default: - DEBUG("No history state"); - break; - } - date = get_formatted_start_timestamp (c); - duration = get_call_duration (c); - duration = g_strconcat( date , duration , NULL); - description = g_strconcat( description , duration, NULL); - } - - //Resize it - if(pixbuf != NULL) - { - if(gdk_pixbuf_get_width(pixbuf) > 32 || gdk_pixbuf_get_height(pixbuf) > 32) - { - pixbuf = gdk_pixbuf_scale_simple(pixbuf, 32, 32, GDK_INTERP_BILINEAR); + switch(c->_srtp_state) + { + case SRTP_STATE_SAS_UNCONFIRMED: + DEBUG("Secure is ON"); + pixbuf_security = gdk_pixbuf_new_from_file(ICONS_DIR "/lock_unconfirmed.svg", NULL); + if(c->_sas != NULL) { DEBUG("SAS is ready with value %s", c->_sas); } + break; + case SRTP_STATE_SAS_CONFIRMED: + DEBUG("SAS is confirmed"); + pixbuf_security = gdk_pixbuf_new_from_file(ICONS_DIR "/lock_confirmed.svg", NULL); + break; + case SRTP_STATE_SAS_SIGNED: + DEBUG("Secure is ON with SAS signed and verified"); + pixbuf_security = gdk_pixbuf_new_from_file(ICONS_DIR "/lock_certified.svg", NULL); + break; + case SRTP_STATE_UNLOCKED: + DEBUG("Secure is off calltree %d", c->_state); + if(g_strcasecmp(srtp_enabled,"true") == 0) { + pixbuf_security = gdk_pixbuf_new_from_file(ICONS_DIR "/lock_off.svg", NULL); } - } - - if(pixbuf_security != NULL) - { - if(gdk_pixbuf_get_width(pixbuf_security) > 32 || gdk_pixbuf_get_height(pixbuf_security) > 32) - { - pixbuf_security = gdk_pixbuf_scale_simple(pixbuf_security, 32, 32, GDK_INTERP_BILINEAR); + break; + default: + WARN("Update calltree srtp state #%d- Should not happen!", c->_srtp_state); + if(g_strcasecmp(srtp_enabled,"true") == 0) { + pixbuf_security = gdk_pixbuf_new_from_file(ICONS_DIR "/lock_off.svg", NULL); } - } - - gtk_list_store_set(store, &iter, - 0, pixbuf, // Icon - 1, description, // Description - 2, pixbuf_security, // Icon - -1); - - if (pixbuf != NULL) - { g_object_unref(G_OBJECT(pixbuf)); } - - if (pixbuf_security != NULL) - { g_object_unref(G_OBJECT(pixbuf_security)); } - } } - + else + { + switch(c->_history_state) + { + case OUTGOING: + DEBUG("Outgoing state"); + pixbuf = gdk_pixbuf_new_from_file( ICONS_DIR "/outgoing.svg", NULL); + break; + case INCOMING: + DEBUG("Incoming state"); + pixbuf = gdk_pixbuf_new_from_file( ICONS_DIR "/incoming.svg", NULL); + break; + case MISSED: + DEBUG("Missed state"); + pixbuf = gdk_pixbuf_new_from_file( ICONS_DIR "/missed.svg", NULL); + break; + default: + DEBUG("No history state"); + break; + } + date = get_formatted_start_timestamp (c); + duration = get_call_duration (c); + duration = g_strconcat( date , duration , NULL); + description = g_strconcat( description , duration, NULL); + } + + //Resize it + if(pixbuf != NULL) + { + if(gdk_pixbuf_get_width(pixbuf) > 32 || gdk_pixbuf_get_height(pixbuf) > 32) + { + pixbuf = gdk_pixbuf_scale_simple(pixbuf, 32, 32, GDK_INTERP_BILINEAR); + } + } + + if(pixbuf_security != NULL) + { + if(gdk_pixbuf_get_width(pixbuf_security) > 32 || gdk_pixbuf_get_height(pixbuf_security) > 32) + { + pixbuf_security = gdk_pixbuf_scale_simple(pixbuf_security, 32, 32, GDK_INTERP_BILINEAR); + } + } + + gtk_list_store_set(store, &iter, + 0, pixbuf, // Icon + 1, description, // Description + 2, pixbuf_security, // Icon + -1); + + if (pixbuf != NULL) + { g_object_unref(G_OBJECT(pixbuf)); } + + if (pixbuf_security != NULL) + { g_object_unref(G_OBJECT(pixbuf_security)); } } + toolbar_update_buttons(); } diff --git a/sflphone-client-gnome/src/dbus/callmanager-introspec.xml b/sflphone-client-gnome/src/dbus/callmanager-introspec.xml index 7b235501d93d5aef21e664a07233ad3bc10afd52..e8f6e1da08d10e37238fcd862727b1aa53ea5a35 100644 --- a/sflphone-client-gnome/src/dbus/callmanager-introspec.xml +++ b/sflphone-client-gnome/src/dbus/callmanager-introspec.xml @@ -100,7 +100,13 @@ <arg type="s" name="callID" direction="out"/> <arg type="s" name="state" direction="out"/> </signal> - + + <signal name="sipCallStateChanged"> + <arg type="s" name="callID" direction="out"/> + <arg type="s" name="state" direction="out"/> + <arg type="i" name="code" direction="out"/> + </signal> + <signal name="voiceMailNotify"> <arg type="s" name="accountID" direction="out"/> <arg type="i" name="count" direction="out"/> diff --git a/sflphone-client-gnome/src/dbus/dbus.c b/sflphone-client-gnome/src/dbus/dbus.c index 970905a6485cff376594907a97c4e50609162344..3700b2308c1d2818dae76ee44a7ec79de4ca1243 100644 --- a/sflphone-client-gnome/src/dbus/dbus.c +++ b/sflphone-client-gnome/src/dbus/dbus.c @@ -319,6 +319,21 @@ zrtp_not_supported_cb (DBusGProxy *proxy UNUSED, } } + static void +sip_call_state_cb (DBusGProxy *proxy UNUSED, + const gchar* callID, + const gchar* description, + const guint code, + void * foo UNUSED ) +{ + callable_obj_t * c = NULL; + c = calllist_get(current_calls, callID); + DEBUG("sip_call_state_cb received code %d callID %s", code, callID); + if(c != NULL) { + DEBUG("sip_call_state_cb received code %d", code); + sflphone_call_state_changed(c, description, code); + } +} static void error_alert(DBusGProxy *proxy UNUSED, @@ -484,6 +499,14 @@ dbus_connect () dbus_g_proxy_connect_signal (callManagerProxy, "confirmGoClear", G_CALLBACK(confirm_go_clear_cb), NULL, NULL); + /* VOID STRING STRING INT */ + dbus_g_object_register_marshaller(g_cclosure_user_marshal_VOID__STRING_STRING_INT, + G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INVALID); + dbus_g_proxy_add_signal (callManagerProxy, + "sipCallStateChanged", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (callManagerProxy, + "sipCallStateChanged", G_CALLBACK(sip_call_state_cb), NULL, NULL); + configurationManagerProxy = dbus_g_proxy_new_for_name (connection, "org.sflphone.SFLphone", "/org/sflphone/SFLphone/ConfigurationManager", diff --git a/sflphone-client-gnome/src/dbus/marshaller.list b/sflphone-client-gnome/src/dbus/marshaller.list index 128b3cc6565627cfee504164dedd591db7758cd7..286e00441d681112e5bd2778342d630252930a9b 100644 --- a/sflphone-client-gnome/src/dbus/marshaller.list +++ b/sflphone-client-gnome/src/dbus/marshaller.list @@ -5,3 +5,4 @@ VOID:STRING,INT VOID:STRING,DOUBLE VOID:STRING VOID:STRING,STRING,BOOL +VOID:STRING, STRING, INT diff --git a/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.cpp b/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.cpp index 3b3a7e7c76100bbea5f09beccde9ffd6bb865a08..ee28caced8c92ca18a2fda56287a4dad30c341a7 100644 --- a/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.cpp +++ b/sflphone-common/src/audio/audiortp/ZrtpSessionCallback.cpp @@ -16,11 +16,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - #include "ZrtpSessionCallback.h" + #include "global.h" -#include "dbus/dbusmanager.h" #include "sip/sipcall.h" +#include "dbus/dbusmanager.h" #include "dbus/callmanager.h" #include <cstdlib> diff --git a/sflphone-common/src/dbus/callmanager-introspec.xml b/sflphone-common/src/dbus/callmanager-introspec.xml index d9917be3492bb8baf60ce4593e24fdac93d5b851..16384ae1edfcf36272f7e977d15a5a819d15214f 100644 --- a/sflphone-common/src/dbus/callmanager-introspec.xml +++ b/sflphone-common/src/dbus/callmanager-introspec.xml @@ -101,6 +101,12 @@ <arg type="s" name="state" direction="out"/> </signal> + <signal name="sipCallStateChanged"> + <arg type="s" name="callID" direction="out"/> + <arg type="s" name="state" direction="out"/> + <arg type="i" name="code" direction="out"/> + </signal> + <signal name="voiceMailNotify"> <arg type="s" name="accountID" direction="out"/> <arg type="i" name="count" direction="out"/> diff --git a/sflphone-common/src/sip/sipvoiplink.cpp b/sflphone-common/src/sip/sipvoiplink.cpp index b6fe24488354dad0154bc90bb35b2a93305324de..efa812bb3b056ac19fde5a1a738c7f45427cbe35 100644 --- a/sflphone-common/src/sip/sipvoiplink.cpp +++ b/sflphone-common/src/sip/sipvoiplink.cpp @@ -24,10 +24,13 @@ #include "manager.h" +#include "sip/sdp.h" #include "sipcall.h" #include "sipaccount.h" #include "eventthread.h" -#include "sip/sdp.h" + +#include "dbus/dbusmanager.h" +#include "dbus/callmanager.h" #include "pjsip/sip_endpoint.h" #include "pjsip/sip_transport_tls.h" @@ -2219,26 +2222,40 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e) { _debug ("call_on_state_changed to state %s\n", invitationStateMap[inv->state]); - SIPCall *call; - AccountID accId; - SIPVoIPLink *link; pjsip_rx_data *rdata; pj_status_t status; /* Retrieve the call information */ + SIPCall * call = NULL; call = reinterpret_cast<SIPCall*> (inv->mod_data[_mod_ua.id]); - if (!call) + if (call == NULL) { + _debug("Call is NULL in call_on_state_changed"); return; + } //Retrieve the body message rdata = e->body.tsx_state.src.rdata; - - /* If this is an outgoing INVITE that was created because of - * REFER/transfer, send NOTIFY to transferer. - */ + // If the call is a direct IP-to-IP call + AccountID accId; + SIPVoIPLink * link = NULL; + if (call->getCallConfiguration () == Call::IPtoIP) { + link = SIPVoIPLink::instance (""); + } else { + accId = Manager::instance().getAccountFromCall (call->getCallId()); + link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (accId)); + } + + if (link == NULL) { + _debug("Link is NULL in call_on_state_changed"); + return; + } + + // If this is an outgoing INVITE that was created because of + // REFER/transfer, send NOTIFY to transferer. if (call->getXferSub() && e->type==PJSIP_EVENT_TSX_STATE) { + int st_code = -1; pjsip_evsub_state ev_state = PJSIP_EVSUB_STATE_ACTIVE; @@ -2298,7 +2315,22 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e) return; } - + + if (inv->state != PJSIP_INV_STATE_CONFIRMED) { + // Update UI with the current status code and description + //pjsip_transaction * tsx + pjsip_transaction * tsx = NULL; + tsx = e->body.tsx_state.tsx; + int statusCode; + if (tsx != NULL) { + statusCode = tsx->status_code; + } + const pj_str_t * description = pjsip_get_status_text(statusCode); + if (statusCode) { + DBusManager::instance().getCallManager()->sipCallStateChanged(call->getCallId(), std::string(description->ptr, description->slen), statusCode); + } + } + // The call is ringing - We need to handle this case only on outgoing call if (inv->state == PJSIP_INV_STATE_EARLY && e->body.tsx_state.tsx->role == PJSIP_ROLE_UAC) { call->setConnectionState (Call::Ringing); @@ -2317,17 +2349,9 @@ void call_on_state_changed (pjsip_inv_session *inv, pjsip_event *e) // After we sent or received a ACK - The connection is established else if (inv->state == PJSIP_INV_STATE_CONFIRMED) { - - /* If the call is a direct IP-to-IP call */ - if (call->getCallConfiguration () == Call::IPtoIP) { - link = SIPVoIPLink::instance (""); - } else { - accId = Manager::instance().getAccountFromCall (call->getCallId()); - link = dynamic_cast<SIPVoIPLink *> (Manager::instance().getAccountLink (accId)); - } - - if (link) + link->SIPCallAnswered (call, rdata); + } else if (inv->state == PJSIP_INV_STATE_DISCONNECTED) { _debug ("State: %s. Cause: %.*s\n", invitationStateMap[inv->state], (int)inv->cause_text.slen, inv->cause_text.ptr); @@ -2434,7 +2458,7 @@ void call_on_forked (pjsip_inv_session *inv, pjsip_event *e) void call_on_tsx_changed (pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e) { _debug ("call_on_tsx_changed to state %s\n", transactionStateMap[tsx->state]); - + if (tsx->role==PJSIP_ROLE_UAS && tsx->state==PJSIP_TSX_STATE_TRYING && pjsip_method_cmp (&tsx->method, &pjsip_refer_method) ==0) { /** Handle the refer method **/ @@ -2444,13 +2468,19 @@ void call_on_tsx_changed (pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_ void regc_cb (struct pjsip_regc_cbparam *param) { - SIPAccount *account; - + SIPAccount * account = NULL; account = static_cast<SIPAccount *> (param->token); - - if (!account) + if (account == NULL) { + _debug("Account is NULL in regc_cb.\n"); return; - + } + + assert(param); + const pj_str_t * description = pjsip_get_status_text(param->code); + if (param->code) { + DBusManager::instance().getCallManager()->sipCallStateChanged(account->getAccountID(), std::string(description->ptr, description->slen), param->code); + } + if (param->status == PJ_SUCCESS) { if (param->code < 0 || param->code >= 300) { /* Sometimes, the status is OK, but we still failed.