From 8ce5a055ae93a0303b8855a2aa76d5ac5f892536 Mon Sep 17 00:00:00 2001 From: Emmanuel Milou Date: Thu, 25 Sep 2008 17:34:28 -0400 Subject: [PATCH] add voicemail notification add a port field in the GTK account window configuration --- sflphone-gtk/src/accountwindow.c | 30 ++++++++--- sflphone-gtk/src/sflphone_const.h | 2 + src/account.h | 2 + src/managerimpl.cpp | 6 ++- src/managerimpl.h | 2 +- src/sipcall.cpp | 1 - src/sipmanager.cpp | 90 +++++++++++++++++++++++++------ src/sipmanager.h | 2 + src/sipvoiplink.cpp | 14 +---- 9 files changed, 109 insertions(+), 40 deletions(-) diff --git a/sflphone-gtk/src/accountwindow.c b/sflphone-gtk/src/accountwindow.c index e6198eafc..4308d94c2 100644 --- a/sflphone-gtk/src/accountwindow.c +++ b/sflphone-gtk/src/accountwindow.c @@ -44,6 +44,7 @@ GtkWidget * entryProtocol; GtkWidget * entryEnabled; GtkWidget * entryUsername; GtkWidget * entryHostname; +GtkWidget * entryPort; GtkWidget * entryPassword; GtkWidget * stunServer; GtkWidget * stunEnable; @@ -104,6 +105,7 @@ show_account_window (account_t * a) gchar * curAlias = ""; gchar * curUsername = ""; gchar * curHostname = ""; + gchar * curPort = "5060"; gchar * curPassword = ""; /* TODO: add curProxy, and add boxes for Proxy support */ gchar * stun_enabled = "FALSE"; @@ -126,6 +128,7 @@ show_account_window (account_t * a) } else if (strcmp(curAccountType, "SIP") == 0) { curHostname = g_hash_table_lookup(currentAccount->properties, ACCOUNT_SIP_HOST); + curPort = g_hash_table_lookup(currentAccount->properties, ACCOUNT_SIP_PORT); curPassword = g_hash_table_lookup(currentAccount->properties, ACCOUNT_SIP_PASSWORD); curUsername = g_hash_table_lookup(currentAccount->properties, ACCOUNT_SIP_USER); stun_enabled = g_hash_table_lookup(currentAccount->properties, ACCOUNT_SIP_STUN_ENABLED); @@ -156,7 +159,7 @@ show_account_window (account_t * a) gtk_box_pack_start(GTK_BOX(dialog->vbox), frame, FALSE, FALSE, 0); gtk_widget_show(frame); - table = gtk_table_new ( 8, 2 , FALSE/* homogeneous */); + table = gtk_table_new ( 9, 2 , FALSE/* homogeneous */); gtk_table_set_row_spacings( GTK_TABLE(table), 10); gtk_table_set_col_spacings( GTK_TABLE(table), 10); gtk_widget_show(table); @@ -224,19 +227,27 @@ show_account_window (account_t * a) gtk_entry_set_text(GTK_ENTRY(entryHostname), curHostname); gtk_table_attach ( GTK_TABLE( table ), entryHostname, 1, 2, 5, 6, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - label = gtk_label_new_with_mnemonic (_("_User name")); + label = gtk_label_new_with_mnemonic (_("_Port")); gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 6, 7, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); + entryPort = gtk_entry_new(); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), entryPort); + gtk_entry_set_text(GTK_ENTRY(entryPort), curPort); + gtk_table_attach ( GTK_TABLE( table ), entryPort, 1, 2, 6, 7, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + label = gtk_label_new_with_mnemonic (_("_User name")); + gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 7, 8, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); entryUsername = sexy_icon_entry_new(); //image = gtk_image_new_from_stock( GTK_STOCK_DIALOG_AUTHENTICATION , GTK_ICON_SIZE_SMALL_TOOLBAR ); image = gtk_image_new_from_file( ICONS_DIR "/stock_person.svg" ); sexy_icon_entry_set_icon( SEXY_ICON_ENTRY(entryUsername), SEXY_ICON_ENTRY_PRIMARY , GTK_IMAGE(image) ); gtk_label_set_mnemonic_widget (GTK_LABEL (label), entryUsername); gtk_entry_set_text(GTK_ENTRY(entryUsername), curUsername); - gtk_table_attach ( GTK_TABLE( table ), entryUsername, 1, 2, 6, 7, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach ( GTK_TABLE( table ), entryUsername, 1, 2, 7, 8, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); label = gtk_label_new_with_mnemonic (_("_Password")); - gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 7, 8, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 8, 9, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); entryPassword = sexy_icon_entry_new(); image = gtk_image_new_from_stock( GTK_STOCK_DIALOG_AUTHENTICATION , GTK_ICON_SIZE_SMALL_TOOLBAR ); @@ -244,15 +255,15 @@ show_account_window (account_t * a) gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE); gtk_label_set_mnemonic_widget (GTK_LABEL (label), entryPassword); gtk_entry_set_text(GTK_ENTRY(entryPassword), curPassword); - gtk_table_attach ( GTK_TABLE( table ), entryPassword, 1, 2, 7, 8, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach ( GTK_TABLE( table ), entryPassword, 1, 2, 8, 9, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); label = gtk_label_new_with_mnemonic (_("_Voicemail box #")); - gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 8, 9, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 9, 10, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5); entryMailbox = gtk_entry_new(); gtk_label_set_mnemonic_widget (GTK_LABEL (label), entryMailbox); gtk_entry_set_text(GTK_ENTRY(entryMailbox), curMailbox); - gtk_table_attach ( GTK_TABLE( table ), entryMailbox, 1, 2, 8, 9, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach ( GTK_TABLE( table ), entryMailbox, 1, 2, 9, 10, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); gtk_widget_show_all( table ); gtk_container_set_border_width (GTK_CONTAINER(table), 10); @@ -327,6 +338,11 @@ show_account_window (account_t * a) g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_SIP_HOST), g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(entryHostname)))); + + g_hash_table_replace(currentAccount->properties, + g_strdup(ACCOUNT_SIP_PORT), + g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(entryPort)))); + g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_SIP_USER), g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(entryUsername)))); diff --git a/sflphone-gtk/src/sflphone_const.h b/sflphone-gtk/src/sflphone_const.h index 097a8cbba..16e8e2fb5 100644 --- a/sflphone-gtk/src/sflphone_const.h +++ b/sflphone-gtk/src/sflphone_const.h @@ -44,6 +44,8 @@ #define ACCOUNT_SIP_USER "SIP.username" /** SIP parameter: password */ #define ACCOUNT_SIP_PASSWORD "SIP.password" +// SIP connection port +#define ACCOUNT_SIP_PORT "SIP.port" /** SIP parameter: proxy address */ #define ACCOUNT_SIP_PROXY "SIP.proxy" /** SIP parameter: stun server address */ diff --git a/src/account.h b/src/account.h index a7b782a03..2d7886309 100644 --- a/src/account.h +++ b/src/account.h @@ -56,6 +56,8 @@ typedef std::string AccountID; #define SIP_PASSWORD "SIP.password" /** SIP parameter : host name */ #define SIP_HOST "SIP.hostPart" +// SIP port +#define SIP_PORT "SIP.port" /** SIP parameter : proxy address */ #define SIP_PROXY "SIP.proxy" /** SIP parameter : stun server address */ diff --git a/src/managerimpl.cpp b/src/managerimpl.cpp index 75ff63ec0..ee874334b 100755 --- a/src/managerimpl.cpp +++ b/src/managerimpl.cpp @@ -696,9 +696,10 @@ ManagerImpl::callFailure(const CallID& id) //THREAD=VoIP void -ManagerImpl::startVoiceMessageNotification(const AccountID& accountId, const std::string& nb_msg) +ManagerImpl::startVoiceMessageNotification(const AccountID& accountId, int nb_msg) { - if (_dbus) _dbus->getCallManager()->voiceMailNotify(accountId, atoi(nb_msg.c_str()) ); + _debug("cccccccccccccccccc\n"); + if (_dbus) _dbus->getCallManager()->voiceMailNotify(accountId, nb_msg) ; } //THREAD=VoIP @@ -2027,6 +2028,7 @@ ManagerImpl::setAccountDetails( const ::DBus::String& accountID, setConfig(accountID, SIP_USER, (*details.find(SIP_USER)).second); setConfig(accountID, SIP_PASSWORD, (*details.find(SIP_PASSWORD)).second); setConfig(accountID, SIP_HOST, (*details.find(SIP_HOST)).second); + //setConfig(accountID, SIP_PORT, (*details.find(SIP_PORT).second)); setConfig(accountID, SIP_STUN_SERVER,(*details.find(SIP_STUN_SERVER)).second); setConfig(accountID, CONFIG_ACCOUNT_MAILBOX,(*details.find(CONFIG_ACCOUNT_MAILBOX)).second); setConfig(accountID, SIP_USE_STUN, diff --git a/src/managerimpl.h b/src/managerimpl.h index 1574c17bb..cd924b949 100755 --- a/src/managerimpl.h +++ b/src/managerimpl.h @@ -260,7 +260,7 @@ class ManagerImpl { * @param accountId The account identifier * @param nb_msg The number of messages */ - void startVoiceMessageNotification(const AccountID& accountId, const std::string& nb_msg); + void startVoiceMessageNotification(const AccountID& accountId, int nb_msg); /** * Notify the user that registration succeeded diff --git a/src/sipcall.cpp b/src/sipcall.cpp index 12bc176d0..ee6a51978 100755 --- a/src/sipcall.cpp +++ b/src/sipcall.cpp @@ -23,7 +23,6 @@ #include "sipcall.h" #include "global.h" // for _debug #include // for media buffer -#include "sipmanager.h" #include #define _SENDRECV 0 diff --git a/src/sipmanager.cpp b/src/sipmanager.cpp index 522daa3b9..27d443edf 100755 --- a/src/sipmanager.cpp +++ b/src/sipmanager.cpp @@ -17,6 +17,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include "manager.h" #include "sipcall.h" @@ -609,19 +610,59 @@ int SIPManager::start_thread(void *arg) { return 0; } +void SIPManager::set_voicemail_info( AccountID account, pjsip_msg_body *body ){ + + int voicemail, pos_begin, pos_end; + std::string voice_str = "Voice-Message: "; + std::string delimiter = "/"; + std::string msg_body, voicemail_str; + + // The voicemail message is formated like that: + // Voice-Message: 1/0 . 1 is the number we want to retrieve in this case + + // We get the notification body + msg_body = (char*)body->data; + std::cout << " body message " << msg_body.c_str() << std::endl; + + // We need the position of the first character of the string voice_str + pos_begin = msg_body.find(voice_str); + // We need the position of the delimiter + pos_end = msg_body.find(delimiter); + + // So our voicemail number between the both index + try { + + voicemail_str = msg_body.substr(pos_begin + voice_str.length(), pos_end - ( pos_begin + voice_str.length())); + std::cout << "voicemail number : " << voicemail_str << std::endl; + voicemail = atoi( voicemail_str.c_str() ); + } + catch( std::out_of_range& e ){ + std::cerr << e.what() << std::endl; + } + + // We need now to notify the manager + if( voicemail != 0 ) + Manager::instance().startVoiceMessageNotification(account, voicemail); +} + + pj_bool_t SIPManager::mod_on_rx_request(pjsip_rx_data *rdata) { + pj_status_t status; pj_str_t reason; unsigned options = 0; pjsip_dialog* dialog; pjsip_tx_data *tdata; pjmedia_sdp_session *r_sdp; + AccountID account_id; - /* Handle the incoming call invite in this function */ + // voicemail part + std::string method_name; + std::string request; + + // Handle the incoming call invite in this function _debug("SIPManager: Callback on_rx_request is involved!\n"); - PJ_UNUSED_ARG(rdata); - /* First, let's got the username and server name from the invite. * We will use them to detect which account is the callee. */ @@ -631,7 +672,16 @@ pj_bool_t SIPManager::mod_on_rx_request(pjsip_rx_data *rdata) { std::string userName = std::string(sip_uri->user.ptr, sip_uri->user.slen); std::string server = std::string(sip_uri->host.ptr, sip_uri->host.slen); + // Get the account id of callee from username and server + account_id = getInstance()->getAccountIdFromNameAndServer(userName, server); + if(account_id == AccountNULL) { + _debug("SIPManager: Username %s doesn't match any account!\n"); + //delete call; + //call = NULL; + return PJ_FALSE; + } _debug("SIPManager: The receiver is : %s@%s\n", userName.data(), server.data()); + _debug("SIPManager: The callee account id is %s\n", account_id.c_str()); /* Now, it is the time to find the information of the caller */ uri = rdata->msg_info.from->uri; @@ -641,7 +691,24 @@ pj_bool_t SIPManager::mod_on_rx_request(pjsip_rx_data *rdata) { std::string callerServer = std::string(sip_uri->host.ptr, sip_uri->host.slen); std::string peerNumber = caller + "@" + callerServer; - /* Respond statelessly any non-INVITE requests with 500 */ + + // Get the server voicemail notification + // Catch the NOTIFY message + if( rdata->msg_info.msg->line.req.method.id == PJSIP_OTHER_METHOD ) + { + method_name = "NOTIFY"; + // Retrieve all the message. Should contains only the method name but ... + request = rdata->msg_info.msg->line.req.method.name.ptr; + _debug("request = %s\n", request.c_str()); + // Check if the message is a notification + if( request.find( method_name ) != -1 ) { + set_voicemail_info( account_id, rdata->msg_info.msg->body ); + } + pjsip_endpt_respond_stateless(getInstance()->getEndPoint(), rdata, PJSIP_SC_OK, NULL, NULL, NULL); + return PJ_SUCCESS; + } + + // Respond statelessly any non-INVITE requests with 500 if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD) { if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) { pj_strdup2(getInstance()->getAppPool(), &reason, "user agent unable to handle this request "); @@ -685,20 +752,11 @@ pj_bool_t SIPManager::mod_on_rx_request(pjsip_rx_data *rdata) { * possilbe audio codec will be used in this call */ if (call->SIPCallInvite(rdata, getInstance()->getAppPool())) { - // Get the account id of callee from username and server - AccountID id = getInstance()->getAccountIdFromNameAndServer(userName, server); - if(id == AccountNULL) { - _debug("SIPManager: Username %s doesn't match any account!\n"); - delete call; - call = NULL; - return PJ_FALSE; - } - _debug("SIPManager: The callee account id is %s\n", id.c_str()); - + // Notify UI there is an incoming call - if (Manager::instance().incomingCall(call, id)) { + if (Manager::instance().incomingCall(call, account_id)) { // Add this call to the callAccountMap in ManagerImpl - Manager::instance().getAccountLink(id)->addCall(call); + Manager::instance().getAccountLink(account_id)->addCall(call); _debug("SIPManager: Notify UI success!\n"); } else { // Fail to notify UI diff --git a/src/sipmanager.h b/src/sipmanager.h index 577b3f554..395a73a9b 100755 --- a/src/sipmanager.h +++ b/src/sipmanager.h @@ -149,6 +149,8 @@ public: static void call_on_tsx_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e); static int start_thread(void *arg); static SIPManager* getInstance() {return _current;} + + static void set_voicemail_info( AccountID account, pjsip_msg_body *body ); }; diff --git a/src/sipvoiplink.cpp b/src/sipvoiplink.cpp index 5cec82447..12ea63669 100755 --- a/src/sipvoiplink.cpp +++ b/src/sipvoiplink.cpp @@ -40,9 +40,6 @@ #define EXOSIP_ERROR_STD -1 #define EXOSIP_ERROR_BUILDING -2 -// for registration -//#define EXPIRES_VALUE 180 - // 1XX responses #define DIALOG_ESTABLISHED 101 // see: osip_const.h @@ -60,7 +57,6 @@ SIPVoIPLink::SIPVoIPLink(const AccountID& accountID) { _evThread = NULL;//new EventThread(this); - _nMsgVoicemail = 0; _eXosipRegID = EXOSIP_ERROR_STD; @@ -793,14 +789,6 @@ SIPVoIPLink::refuse (const CallID& id) } Manager::instance().getSipManager()->refuse(call); - /*osip_message_t *answerMessage = NULL; - eXosip_lock(); - // not BUSY.. where decline the invitation! - int exosipErr = eXosip_call_build_answer(call->getTid(), SIP_DECLINE, &answerMessage); - if (exosipErr == 0) { - exosipErr = eXosip_call_send_answer(call->getTid(), SIP_DECLINE, answerMessage); - } - eXosip_unlock();*/ return true; } @@ -1482,7 +1470,7 @@ SIPVoIPLink::SIPMessageNew(eXosip_event_t *event) if (msgVoicemail != 0) { // If there is at least one voice-message, start notification - Manager::instance().startVoiceMessageNotification(getAccountID(), nb_msg); + //Manager::instance().startVoiceMessageNotification(getAccountID(), nb_msg); } // http://www.jdrosen.net/papers/draft-ietf-simple-im-session-00.txt } else if (MSG_IS_MESSAGE(event->request)) {