diff --git a/sflphone-client-gnome/src/contacts/calltree.c b/sflphone-client-gnome/src/contacts/calltree.c index df957319f202f14e084fc8481506fe93673b3ce1..0cd39f053ecddca98825240ce792bb001fdd4844 100644 --- a/sflphone-client-gnome/src/contacts/calltree.c +++ b/sflphone-client-gnome/src/contacts/calltree.c @@ -1674,8 +1674,12 @@ static void drag_end_cb (GtkWidget * widget UNUSED, GdkDragContext * context UNU // dragged a conference call on a call sflphone_detach_participant (selected_call_id); - if (selected_call != NULL && dragged_call != NULL) - sflphone_join_participant (selected_call->_callID, dragged_call->_callID); + if (selected_call != NULL && dragged_call != NULL) { + // sflphone_join_participant (selected_call->_callID, dragged_call->_callID); + gtk_menu_popup (GTK_MENU (popupmenu), NULL, NULL, NULL, NULL, + 0, 0); + + } } else if (selected_type == A_CALL && dragged_type == A_CONFERENCE) { diff --git a/sflphone-common/src/iax/iaxvoiplink.cpp b/sflphone-common/src/iax/iaxvoiplink.cpp index 0e09de41e7d636f1907784c11bf0c304f6224250..dc8ab5569db8f810a8e14bddd57ff4611bde6327 100644 --- a/sflphone-common/src/iax/iaxvoiplink.cpp +++ b/sflphone-common/src/iax/iaxvoiplink.cpp @@ -496,7 +496,7 @@ IAXVoIPLink::sendUnregister (AccountID id UNUSED) } Call* -IAXVoIPLink::newOutgoingCall (const CallID& id, const std::string& toUrl) +IAXVoIPLink::newOutgoingCall (const CallID& id, const std::string& toUrl) throw(VoipLinkException) { IAXCall* call = new IAXCall (id, Call::Outgoing); call->setCodecMap (Manager::instance().getCodecDescriptorMap()); diff --git a/sflphone-common/src/iax/iaxvoiplink.h b/sflphone-common/src/iax/iaxvoiplink.h index 5382a0e81e2140ba5805184c04d5ef7eaeb9fe69..a7776542705f32508e392cbc680921ce7672fea1 100644 --- a/sflphone-common/src/iax/iaxvoiplink.h +++ b/sflphone-common/src/iax/iaxvoiplink.h @@ -112,7 +112,7 @@ class IAXVoIPLink : public VoIPLink * @param toUrl The address to call * @return Call* A pointer on the call */ - virtual Call* newOutgoingCall (const CallID& id, const std::string& toUrl); + virtual Call* newOutgoingCall (const CallID& id, const std::string& toUrl) throw(VoipLinkException); /** * Answer a call diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp index 6c71af64b490f40029b563580cac09b6a8f34af3..3e4a9a1848e82fc53e237e92910a789d831be321 100644 --- a/sflphone-common/src/managerimpl.cpp +++ b/sflphone-common/src/managerimpl.cpp @@ -283,7 +283,7 @@ bool ManagerImpl::outgoingCall (const std::string& account_id, /* We need to retrieve the sip voiplink instance */ siplink = SIPVoIPLink::instance (""); - if (siplink->new_ip_to_ip_call (call_id, to_cleaned)) { + if (siplink->SIPNewIpToIpCall(call_id, to_cleaned)) { switchCall (call_id); return true; } else { diff --git a/sflphone-common/src/sip/sipaccount.cpp b/sflphone-common/src/sip/sipaccount.cpp index 693a3e9fc1a1643d5b6196bc7767afb502237d9e..d3357eb10dcb9977c23664947ef0d711951ec271 100644 --- a/sflphone-common/src/sip/sipaccount.cpp +++ b/sflphone-common/src/sip/sipaccount.cpp @@ -81,6 +81,7 @@ void Credentials::unserialize (Conf::MappingNode *map) SIPAccount::SIPAccount (const AccountID& accountID) : Account (accountID, "SIP") , _routeSet ("") + , _pool (NULL) , _regc (NULL) , _bRegister (false) , _registrationExpire ("") @@ -124,7 +125,7 @@ SIPAccount::SIPAccount (const AccountID& accountID) , _zrtpNotSuppWarning (true) { - _debug ("Sip account constructor called"); + _debug ("Sip account constructor for account %s", accountID.c_str()); _stunServerName.ptr = NULL; _stunServerName.slen = 0; diff --git a/sflphone-common/src/sip/sipaccount.h b/sflphone-common/src/sip/sipaccount.h index 388e34bd35575ac8adcdeb16202a8649d73e73d8..afe8f8331bbf0ba013555b4a43bbfd5f83ba72b8 100644 --- a/sflphone-common/src/sip/sipaccount.h +++ b/sflphone-common/src/sip/sipaccount.h @@ -50,7 +50,6 @@ enum DtmfType { OVERRTP, SIPINFO}; #define OVERRTPSTR "overrtp" #define SIPINFOSTR "sipinfo" - // SIP specific configuration keys const Conf::Key expireKey ("expire"); const Conf::Key interfaceKey ("interface"); @@ -695,6 +694,16 @@ class SIPAccount : public Account private: + /** + * Call specific memory pool initialization size (based on empirical data) + */ + static const int ACCOUNT_MEMPOOL_INIT_SIZE; + + /** + * Call specific memory pool incrementation size + */ + static const int ACCOUNT_MEMPOOL_INC_SIZE; + /* Maps a string description of the SSL method * to the corresponding enum value in pjsip_ssl_method. * @param method The string representation @@ -734,8 +743,16 @@ class SIPAccount : public Account */ std::string getLoginName (void); + /** + * List of routes (proxies) used for registration and calls + */ std::string _routeSet; + /** + * Private pjsip memory pool for accounts + */ + pj_pool_t *_pool; + // The pjsip client registration information pjsip_regc *_regc; diff --git a/sflphone-common/src/sip/sipcall.cpp b/sflphone-common/src/sip/sipcall.cpp index 17476ad1e435d8da48a5287765e6abb709774666..91c1fca6bdc9d1a0e9e794f9a7e0bfa70cc90d62 100644 --- a/sflphone-common/src/sip/sipcall.cpp +++ b/sflphone-common/src/sip/sipcall.cpp @@ -46,6 +46,7 @@ SIPCall::SIPCall (const CallID& id, Call::CallType type, pj_caching_pool *cachin , _xferSub (NULL) , _invSession (NULL) , _local_sdp (NULL) + , _pool(NULL) { _debug ("SIPCall: Create new call %s", id.c_str()); @@ -68,7 +69,7 @@ SIPCall::~SIPCall() _debug ("SDP: pool capacity %d", pj_pool_get_capacity (_pool)); _debug ("SDP: pool size %d", pj_pool_get_used_size (_pool)); - // Release memory allocated for SDP only once + // Release memory allocated for SDP pj_pool_release (_pool); _pool = NULL; diff --git a/sflphone-common/src/sip/sipvoiplink.cpp b/sflphone-common/src/sip/sipvoiplink.cpp index db38c7cb935571fc93d3c1799c7b29999cb360d7..93da739a008775082aaff767328c763246f781f4 100644 --- a/sflphone-common/src/sip/sipvoiplink.cpp +++ b/sflphone-common/src/sip/sipvoiplink.cpp @@ -335,7 +335,7 @@ bool SIPVoIPLink::init() _evThread = new EventThread (this); /* Initialize the pjsip library */ - pjsip_init(); + pjsipInit(); initDone (true); @@ -364,95 +364,6 @@ SIPVoIPLink::terminate() } -void -SIPVoIPLink::terminateCall (const CallID& id) -{ - _debug ("UserAgent: Terminate call %s", id.c_str()); - - SIPCall *call = getSIPCall (id); - - if (call) { - // terminate the sip call - delete call; - call = 0; - } -} - -void getRemoteSdpFromOffer (pjsip_rx_data *rdata, pjmedia_sdp_session** r_sdp) -{ - - pjmedia_sdp_session *sdp; - pjsip_msg *msg; - pjsip_msg_body *body; - - // Get the message - msg = rdata->msg_info.msg; - // Get the body message - body = msg->body; - - // Parse the remote request to get the sdp session - - if (body) { - pjmedia_sdp_parse (rdata->tp_info.pool, (char*) body->data, body->len, &sdp); - *r_sdp = sdp; - } - - else - *r_sdp = NULL; -} - - -std::string SIPVoIPLink::getInterfaceAddrFromName (std::string ifaceName) -{ - - struct ifreq ifr; - int fd; - int err; - - struct sockaddr_in *saddr_in; - struct in_addr *addr_in; - - if ( (fd = socket (AF_INET, SOCK_DGRAM,0)) < 0) - _error ("UserAgent: Error: could not open socket"); - - memset (&ifr, 0, sizeof (struct ifreq)); - - strcpy (ifr.ifr_name, ifaceName.c_str()); - ifr.ifr_addr.sa_family = AF_INET; - - if ( (err = ioctl (fd, SIOCGIFADDR, &ifr)) < 0) - _debug ("UserAgent: Use default interface (0.0.0.0)"); - - saddr_in = (struct sockaddr_in *) &ifr.ifr_addr; - addr_in = & (saddr_in->sin_addr); - - std::string addr (pj_inet_ntoa (* ( (pj_in_addr*) addr_in))); - - close (fd); - - return addr; -} - - -std::string SIPVoIPLink::get_useragent_name (const AccountID& id) -{ - /* - useragent << PROGNAME << "/" << SFLPHONED_VERSION; - return useragent.str(); - */ - - SIPAccount *account = (SIPAccount *) Manager::instance().getAccount (id); - - std::ostringstream useragent; - - useragent << account->getUseragent(); - - if (useragent.str() == "sflphone" || useragent.str() == "") - useragent << "/" << SFLPHONED_VERSION; - - return useragent.str (); -} - void SIPVoIPLink::getEvent() { @@ -619,7 +530,7 @@ int SIPVoIPLink::sendRegister (AccountID id) // Add User-Agent Header pj_list_init (&hdr_list); - const char *useragent_name = get_useragent_name (id).c_str(); + const char *useragent_name = getUseragentName (id).c_str(); pj_str_t useragent = pj_str ( (char *) useragent_name); pjsip_generic_string_hdr *h = pjsip_generic_string_hdr_create (_pool, &STR_USER_AGENT, &useragent); @@ -635,7 +546,7 @@ int SIPVoIPLink::sendRegister (AccountID id) pjsip_tpselector *tp; - init_transport_selector (account->getAccountTransport (), &tp); + initTransportSelector (account->getAccountTransport (), &tp); // pjsip_regc_set_transport increments transport ref count by one status = pjsip_regc_set_transport (regc, tp); @@ -742,8 +653,7 @@ SIPVoIPLink::sendUnregister (AccountID id) return true; } -Call* -SIPVoIPLink::newOutgoingCall (const CallID& id, const std::string& toUrl) throw (SIPVoipLinkException) +Call *SIPVoIPLink::newOutgoingCall (const CallID& id, const std::string& toUrl) throw (VoipLinkException) // throw (SIPVoipLinkException) { SIPAccount * account = NULL; pj_status_t status; @@ -755,80 +665,80 @@ SIPVoIPLink::newOutgoingCall (const CallID& id, const std::string& toUrl) throw _debug ("UserAgent: pool size %d", pj_pool_get_used_size (_pool)); SIPCall* call = new SIPCall (id, Call::Outgoing, _cp); + if(call == NULL) { + return NULL; + } - if (call) { - account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount (Manager::instance().getAccountFromCall (id))); - if (account == NULL) { - _error ("UserAgent: Error: Could not retrieving account to make call with"); - call->setConnectionState (Call::Disconnected); - call->setState (Call::Error); - delete call; - call=0; - return call; - } + account = dynamic_cast<SIPAccount *> (Manager::instance().getAccount (Manager::instance().getAccountFromCall (id))); + if (account == NULL) { + _error ("UserAgent: Error: Could not retrieving account to make call with"); + call->setConnectionState (Call::Disconnected); + call->setState (Call::Error); + delete call; + call = NULL; + return call; + } - std::string toUri = account->getToUri (toUrl); + std::string toUri = account->getToUri (toUrl); + call->setPeerNumber (toUri); - call->setPeerNumber (toUri); + localAddr = getInterfaceAddrFromName (account->getLocalInterface ()); - localAddr = getInterfaceAddrFromName (account->getLocalInterface ()); + _debug ("UserAgent: Local address for call: %s", localAddr.c_str()); - _debug ("UserAgent: Local address for call: %s", localAddr.c_str()); + if (localAddr == "0.0.0.0") + loadSIPLocalIP (&localAddr); - if (localAddr == "0.0.0.0") - loadSIPLocalIP (&localAddr); + setCallAudioLocal (call, localAddr); - setCallAudioLocal (call, localAddr); + // May use the published address as well + account->isStunEnabled () ? addrSdp = account->getPublishedAddress () : addrSdp = getInterfaceAddrFromName (account->getLocalInterface ()); - // May use the published address as well - account->isStunEnabled () ? addrSdp = account->getPublishedAddress () : addrSdp = getInterfaceAddrFromName (account->getLocalInterface ()); + if (addrSdp == "0.0.0.0") + loadSIPLocalIP (&addrSdp); - if (addrSdp == "0.0.0.0") - loadSIPLocalIP (&addrSdp); - - AudioCodec* audiocodec = Manager::instance().getCodecDescriptorMap().instantiateCodec (PAYLOAD_CODEC_ULAW); + AudioCodec* audiocodec = Manager::instance().getCodecDescriptorMap().instantiateCodec (PAYLOAD_CODEC_ULAW); - if (audiocodec == NULL) { - _error ("UserAgent: Could not instantiate codec"); - throw SIPVoipLinkException ("Could not instantiate codec"); - } + if (audiocodec == NULL) { + _error ("UserAgent: Could not instantiate codec"); + throw VoipLinkException ("Could not instantiate codec"); + } - try { - _info ("UserAgent: Creating new rtp session"); - call->getAudioRtp()->initAudioRtpConfig (call); - call->getAudioRtp()->initAudioRtpSession (call); - call->getAudioRtp()->initLocalCryptoInfo (call); - _info ("UserAgent: Start audio rtp session"); - call->getAudioRtp()->start (audiocodec); - } catch (...) { - _error ("UserAgent: Error: Failed to create rtp thread from newOutGoingCall"); - } + try { + _info ("UserAgent: Creating new rtp session"); + call->getAudioRtp()->initAudioRtpConfig (call); + call->getAudioRtp()->initAudioRtpSession (call); + call->getAudioRtp()->initLocalCryptoInfo (call); + _info ("UserAgent: Start audio rtp session"); + call->getAudioRtp()->start (audiocodec); + } catch (...) { + _error ("UserAgent: Error: Failed to create rtp thread from newOutGoingCall"); + } - // init file name according to peer phone number - call->initRecFileName (toUrl); + // init file name according to peer phone number + call->initRecFileName (toUrl); - _debug ("UserAgent: Try to make a call to: %s with call ID: %s", toUrl.data(), id.data()); + _debug ("UserAgent: Try to make a call to: %s with call ID: %s", toUrl.data(), id.data()); - // Building the local SDP offer - call->getLocalSDP()->set_ip_address (addrSdp); - status = call->getLocalSDP()->create_initial_offer (account->getActiveCodecs ()); + // Building the local SDP offer + call->getLocalSDP()->set_ip_address (addrSdp); + status = call->getLocalSDP()->create_initial_offer (account->getActiveCodecs ()); - if (status != PJ_SUCCESS) { - delete call; - call=0; - return call; - } + if (status != PJ_SUCCESS) { + delete call; + call = NULL; + return call; + } - if (SIPOutgoingInvite (call)) { - call->setConnectionState (Call::Progressing); - call->setState (Call::Active); - addCall (call); - } else { - delete call; - call = 0; - } - } + if (SIPOutgoingInvite (call)) { + call->setConnectionState (Call::Progressing); + call->setState (Call::Active); + addCall (call); + } else { + delete call; + call = NULL; + } return call; } @@ -1038,7 +948,7 @@ SIPVoIPLink::onhold (const CallID& id) call->getAudioRtp()->stop(); /* Create re-INVITE with new offer */ - status = inv_session_reinvite (call, "sendonly"); + status = SIPInvSessionReinvite (call, "sendonly"); if (status != PJ_SUCCESS) return false; @@ -1084,7 +994,7 @@ SIPVoIPLink::sendTextMessage (sfl::InstantMessaging *module, const std::string& return status; } -int SIPVoIPLink::inv_session_reinvite (SIPCall *call, std::string direction) +int SIPVoIPLink::SIPInvSessionReinvite (SIPCall *call, std::string direction) { pj_status_t status; @@ -1185,7 +1095,7 @@ SIPVoIPLink::offhold (const CallID& id) } /* Create re-INVITE with new offer */ - status = inv_session_reinvite (call, "sendrecv"); + status = SIPInvSessionReinvite (call, "sendrecv"); if (status != PJ_SUCCESS) return false; @@ -1425,6 +1335,19 @@ SIPVoIPLink::refuse (const CallID& id) return true; } +void +SIPVoIPLink::terminateCall (const CallID& id) +{ + _debug ("UserAgent: Terminate call %s", id.c_str()); + + SIPCall *call = getSIPCall (id); + + if (call) { + // terminate the sip call + delete call; + call = 0; + } +} std::string SIPVoIPLink::getCurrentCodecName() @@ -1445,6 +1368,25 @@ SIPVoIPLink::getCurrentCodecName() return name; } +std::string SIPVoIPLink::getUseragentName (const AccountID& id) +{ + /* + useragent << PROGNAME << "/" << SFLPHONED_VERSION; + return useragent.str(); + */ + + SIPAccount *account = (SIPAccount *) Manager::instance().getAccount (id); + + std::ostringstream useragent; + + useragent << account->getUseragent(); + + if (useragent.str() == "sflphone" || useragent.str() == "") + useragent << "/" << SFLPHONED_VERSION; + + return useragent.str (); +} + bool SIPVoIPLink::carryingDTMFdigits (const CallID& id, char code) { @@ -1567,14 +1509,12 @@ SIPVoIPLink::SIPStartCall (SIPCall* call, const std::string& subject UNUSED) pjsip_dialog *dialog; pjsip_tx_data *tdata; - AccountID id; - _debug ("UserAgent: Start sip call"); if (call == NULL) return false; - id = Manager::instance().getAccountFromCall (call->getCallId()); + AccountID id = Manager::instance().getAccountFromCall (call->getCallId()); // Get the basic information about the callee account SIPAccount * account = NULL; @@ -1618,7 +1558,6 @@ SIPVoIPLink::SIPStartCall (SIPCall* call, const std::string& subject UNUSED) &pjTo, NULL, &dialog); - if (status != PJ_SUCCESS) { _error ("UserAgent: Error: UAC creation failed"); return false; @@ -1627,12 +1566,10 @@ SIPVoIPLink::SIPStartCall (SIPCall* call, const std::string& subject UNUSED) // Create the invite session for this call status = pjsip_inv_create_uac (dialog, call->getLocalSDP()->get_local_sdp_session(), 0, &inv); - if (! (account->getServiceRoute().empty())) { pjsip_route_hdr *route_set = createRouteSet(account); pjsip_dlg_set_route_set (dialog, route_set); } - PJ_ASSERT_RETURN (status == PJ_SUCCESS, false); // Set auth information @@ -1642,7 +1579,6 @@ SIPVoIPLink::SIPStartCall (SIPCall* call, const std::string& subject UNUSED) inv->mod_data[getModId() ] = call; status = pjsip_inv_invite (inv, &tdata); - PJ_ASSERT_RETURN (status == PJ_SUCCESS, false); // Associate current invite session in the call @@ -1651,20 +1587,14 @@ SIPVoIPLink::SIPStartCall (SIPCall* call, const std::string& subject UNUSED) // Set the appropriate transport pjsip_tpselector *tp; - init_transport_selector (account->getAccountTransport (), &tp); + initTransportSelector (account->getAccountTransport (), &tp); // increment transport's ref count by one status = pjsip_dlg_set_transport (dialog, tp); - - // decrement transport's ref count - // pjsip_transport_dec_ref(account->getAccountTransport()); + PJ_ASSERT_RETURN (status == PJ_SUCCESS, false); status = pjsip_inv_send_msg (inv, tdata); - - if (status != PJ_SUCCESS) { - _error ("UserAgent: Error: failed to send invite"); - return false; - } + PJ_ASSERT_RETURN (status == PJ_SUCCESS, false); if (account->getAccountTransport()) { @@ -1767,7 +1697,7 @@ SIPVoIPLink::getSIPCall (const CallID& id) return NULL; } -bool SIPVoIPLink::new_ip_to_ip_call (const CallID& id, const std::string& to) +bool SIPVoIPLink::SIPNewIpToIpCall (const CallID& id, const std::string& to) { SIPCall *call; pj_status_t status; @@ -1915,7 +1845,7 @@ bool SIPVoIPLink::new_ip_to_ip_call (const CallID& id, const std::string& to) // Set the appropriate transport pjsip_tpselector *tp; - init_transport_selector (account->getAccountTransport(), &tp); + initTransportSelector (account->getAccountTransport(), &tp); if (!account->getAccountTransport()) { _error ("UserAgent: Error: Transport is NULL in IP2IP call"); @@ -1965,7 +1895,7 @@ bool SIPVoIPLink::new_ip_to_ip_call (const CallID& id, const std::string& to) // Private functions /////////////////////////////////////////////////////////////////////////////// -bool SIPVoIPLink::pjsip_init() +bool SIPVoIPLink::pjsipInit() { pj_status_t status; pjsip_inv_callback inv_cb; @@ -2619,7 +2549,7 @@ std::string SIPVoIPLink::findLocalAddressFromUri (const std::string& uri, pjsip_ //_debug ("Transport ID: %s", transport->obj_name); if (transportType == PJSIP_TRANSPORT_UDP) { - status = init_transport_selector (transport, &tp_sel); + status = initTransportSelector (transport, &tp_sel); if (status == PJ_SUCCESS) { status = pjsip_tpmgr_find_local_addr (tpmgr, _pool, transportType, tp_sel, &localAddress, &port); @@ -2647,7 +2577,7 @@ std::string SIPVoIPLink::findLocalAddressFromUri (const std::string& uri, pjsip_ -pj_status_t SIPVoIPLink::init_transport_selector (pjsip_transport *transport, pjsip_tpselector **tp_sel) +pj_status_t SIPVoIPLink::initTransportSelector (pjsip_transport *transport, pjsip_tpselector **tp_sel) { pjsip_tpselector *tp; @@ -2725,7 +2655,7 @@ int SIPVoIPLink::findLocalPortFromUri (const std::string& uri, pjsip_transport * if (transportType == PJSIP_TRANSPORT_UDP) { _debug ("UserAgent: transport ID: %s", transport->obj_name); - status = init_transport_selector (transport, &tp_sel); + status = initTransportSelector (transport, &tp_sel); if (status == PJ_SUCCESS) status = pjsip_tpmgr_find_local_addr (tpmgr, _pool, transportType, tp_sel, &localAddress, &port); @@ -3047,7 +2977,7 @@ bool SIPVoIPLink::dnsResolution(pjsip_tx_data *tdata) { return true; } -void SIPVoIPLink::busy_sleep (unsigned msec) +void SIPVoIPLink::busySleep (unsigned msec) { #if defined(PJ_SYMBIAN) && PJ_SYMBIAN != 0 @@ -3079,7 +3009,7 @@ bool SIPVoIPLink::pjsip_shutdown (void) { if (_endpt) { _debug ("UserAgent: Shutting down..."); - busy_sleep (1000); + busySleep (1000); } pj_thread_join (thread); @@ -3165,7 +3095,7 @@ void setVoicemailInfo (AccountID account, pjsip_msg_body *body) Manager::instance().startVoiceMessageNotification (account, voicemail); } -void SIPVoIPLink::handle_reinvite (SIPCall *call UNUSED) +void SIPVoIPLink::SIPHandleReinvite (SIPCall *call UNUSED) { _debug ("UserAgent: Handle reinvite"); } @@ -3871,7 +3801,7 @@ transaction_request_cb (pjsip_rx_data *rdata) addrToUse = SIPVoIPLink::instance ("")->getInterfaceAddrFromName (account->getLocalInterface ()); account->isStunEnabled () ? addrSdp = account->getPublishedAddress () : addrSdp = addrToUse; // Set the appropriate transport to have the right VIA header - link->init_transport_selector (account->getAccountTransport (), &tp); + link->initTransportSelector (account->getAccountTransport (), &tp); if (account->getAccountTransport()) { @@ -4527,7 +4457,7 @@ void invite_request_offer_cb (pjsip_inv_session *inv, const pjmedia_sdp_session status=pjsip_inv_set_sdp_answer (call->getInvSession(), call->getLocalSDP()->get_local_sdp_session()); if (link) - link->handle_reinvite (call); + link->SIPHandleReinvite (call); #endif @@ -4786,6 +4716,37 @@ std::vector<std::string> SIPVoIPLink::getAllIpInterfaceByName (void) return ifaceList; } +std::string SIPVoIPLink::getInterfaceAddrFromName (std::string ifaceName) +{ + + struct ifreq ifr; + int fd; + int err; + + struct sockaddr_in *saddr_in; + struct in_addr *addr_in; + + if ( (fd = socket (AF_INET, SOCK_DGRAM,0)) < 0) + _error ("UserAgent: Error: could not open socket"); + + memset (&ifr, 0, sizeof (struct ifreq)); + + strcpy (ifr.ifr_name, ifaceName.c_str()); + ifr.ifr_addr.sa_family = AF_INET; + + if ( (err = ioctl (fd, SIOCGIFADDR, &ifr)) < 0) + _debug ("UserAgent: Use default interface (0.0.0.0)"); + + saddr_in = (struct sockaddr_in *) &ifr.ifr_addr; + addr_in = & (saddr_in->sin_addr); + + std::string addr (pj_inet_ntoa (* ( (pj_in_addr*) addr_in))); + + close (fd); + + return addr; +} + pj_bool_t stun_sock_on_status_cb (pj_stun_sock *stun_sock UNUSED, pj_stun_sock_op op UNUSED, pj_status_t status) { @@ -4835,3 +4796,27 @@ std::string getLocalAddressAssociatedToAccount (AccountID id) return localAddr; } + +void getRemoteSdpFromOffer (pjsip_rx_data *rdata, pjmedia_sdp_session** r_sdp) +{ + + pjmedia_sdp_session *sdp; + pjsip_msg *msg; + pjsip_msg_body *body; + + // Get the message + msg = rdata->msg_info.msg; + // Get the body message + body = msg->body; + + // Parse the remote request to get the sdp session + + if (body) { + pjmedia_sdp_parse (rdata->tp_info.pool, (char*) body->data, body->len, &sdp); + *r_sdp = sdp; + } + + else + *r_sdp = NULL; +} + diff --git a/sflphone-common/src/sip/sipvoiplink.h b/sflphone-common/src/sip/sipvoiplink.h index 3d3523b50ead8f0156044be9e3dcbd6158ffd722..9fdf4446a8d28be17f8e2625a8069cccc33fe92e 100644 --- a/sflphone-common/src/sip/sipvoiplink.h +++ b/sflphone-common/src/sip/sipvoiplink.h @@ -61,8 +61,6 @@ class SIPCall; // To set the verbosity. From 0 (min) to 6 (max) #define PJ_LOG_LEVEL 6 -#define SipTransportMap std::map<std::string, pjsip_transport*> - class SIPVoipLinkException : public std::exception { public: @@ -88,7 +86,20 @@ class SIPVoipLinkException : public std::exception class SIPVoIPLink : public VoIPLink { - public: + typedef std::map<std::string, pjsip_transport*> SipTransportMap; + + public: + + /* Copy Constructor */ + SIPVoIPLink (const SIPVoIPLink& rh); + + /** + * Destructor + */ + ~SIPVoIPLink(); + + /* Assignment Operator */ + SIPVoIPLink& operator= (const SIPVoIPLink& rh); /** * Singleton method. Enable to retrieve the unique static instance @@ -97,15 +108,16 @@ class SIPVoIPLink : public VoIPLink static SIPVoIPLink* instance (const AccountID& id); /** - * Destructor + * Increment the number of SIP account connected to this link */ - ~SIPVoIPLink(); - - /* Copy Constructor */ - SIPVoIPLink (const SIPVoIPLink& rh); + void incrementClients (void) { + _clients++; + } - /* Assignment Operator */ - SIPVoIPLink& operator= (const SIPVoIPLink& rh); + /** + * Decrement the number of SIP account connected to this link + */ + void decrementClients (void); /** * Try to initiate the pjsip engine/thread and set config @@ -143,7 +155,7 @@ class SIPVoIPLink : public VoIPLink * @param toUrl The Sip address of the recipient of the call * @return Call* The current call */ - Call* newOutgoingCall (const CallID& id, const std::string& toUrl) throw (SIPVoipLinkException); + virtual Call* newOutgoingCall (const CallID& id, const std::string& toUrl) throw (VoipLinkException); /** * Answer the call @@ -215,6 +227,11 @@ class SIPVoIPLink : public VoIPLink */ virtual bool refuse (const CallID& id); + /** + * Terminate only one call + */ + virtual void terminateCall (const CallID& id); + /** * Send DTMF refering to account configuration * @param id The call identifier @@ -233,11 +250,6 @@ class SIPVoIPLink : public VoIPLink */ bool dtmfOverRtp (SIPCall* call, char code); - /** - * Terminate only one call - */ - virtual void terminateCall (const CallID& id); - /** * Send an outgoing call invite * @param call The current call @@ -253,6 +265,13 @@ class SIPVoIPLink : public VoIPLink */ bool SIPStartCall (SIPCall* call, const std::string& subject); + /** + * Start a new SIP call using the IP2IP profile + * @param The call id + * @param The target sip uri + */ + bool SIPNewIpToIpCall (const CallID& id, const std::string& to); + /** * Tell the user that the call was answered * @param @@ -274,46 +293,34 @@ class SIPVoIPLink : public VoIPLink /** * The call pointer was released * If the call was not cleared before, report an error - * @param + * @param sip call */ void SIPCallReleased (SIPCall *call); /** * Handle a re-invite request by the remote peer. * A re-invite is an invite request inside a dialog. - * When receiving a re-invite, we close the current rtp session and create a new one with the updated information + * When receiving a re-invite, we close the current rtp session and create + * a new one with the updated information + * @param sip call */ - void handle_reinvite (SIPCall *call); + void SIPHandleReinvite (SIPCall *call); /** - * SIPCall accessor - * @param id The call identifier - * @return SIPCall* A pointer on SIPCall object + * Send a reINVITE inside an active dialog to modify its state + * @param sip call + * @param the direction, "sendrecv" or "sendonly" */ - SIPCall* getSIPCall (const CallID& id); - - /** when we init the listener, how many times we try to bind a port? */ - int _nbTryListenAddr; + int SIPInvSessionReinvite (SIPCall *call, std::string direction=""); - /** Increment the number of SIP account connected to this link */ - void incrementClients (void) { - _clients++; - } - - /** Decrement the number of SIP account connected to this link */ - void decrementClients (void); - - /** - * Set Recording - * @param id The call identifier - */ - void setRecording (const CallID& id); + pj_caching_pool *getMemoryPoolFactory(); /** - * Returning state (true recording) - * @param id The call identifier + * SIPCall accessor + * @param id The call identifier + * @return SIPCall* A pointer on SIPCall object */ - bool isRecording (const CallID& id); + SIPCall* getSIPCall (const CallID& id); /** * Return the codec protocol used for this call @@ -321,11 +328,10 @@ class SIPVoIPLink : public VoIPLink */ std::string getCurrentCodecName(); - int inv_session_reinvite (SIPCall *call, std::string direction=""); - - bool new_ip_to_ip_call (const CallID& id, const std::string& to); - - std::string get_useragent_name (const AccountID& id); + /** + * Retrive useragent name from account + */ + std::string getUseragentName (const AccountID& id); /** * List all the interfaces on the system and return @@ -337,7 +343,6 @@ class SIPVoIPLink : public VoIPLink */ std::vector<std::string> getAllIpInterface (void); - /** * List all the interfaces on the system and return * a vector list containing their name (eth0, eth0:1 ...). @@ -348,18 +353,16 @@ class SIPVoIPLink : public VoIPLink */ std::vector<std::string> getAllIpInterfaceByName (void); - /** - * List all the interfaces on the system and return - * a vector list containing their name (eth0, eth0:1 ...). - * @param void - * @return std::vector<std::string> A std::string vector - * of interface name available on all of the interfaces on - * the system. - */ + * List all the interfaces on the system and return + * a vector list containing their name (eth0, eth0:1 ...). + * @param void + * @return std::vector<std::string> A std::string vector + * of interface name available on all of the interfaces on + * the system. + */ std::string getInterfaceAddrFromName (std::string ifaceName); - /** * Initialize the transport selector * @param transport A transport associated with an account @@ -367,7 +370,7 @@ class SIPVoIPLink : public VoIPLink * * @return pj_status_t PJ_SUCCESS if the structure was successfully initialized */ - pj_status_t init_transport_selector (pjsip_transport *transport, pjsip_tpselector **tp_sel); + pj_status_t initTransportSelector (pjsip_transport *transport, pjsip_tpselector **tp_sel); /** * Requests PJSIP library for local IP address, using pj_gethostbyname() @@ -378,7 +381,8 @@ class SIPVoIPLink : public VoIPLink bool loadSIPLocalIP (std::string *addr); /** - * Helper function for creating a route set + * Helper function for creating a route set from information + * stored in configuration file. */ pjsip_route_hdr *createRouteSet(Account *account); @@ -395,11 +399,10 @@ class SIPVoIPLink : public VoIPLink */ void shutdownSipTransport (const AccountID& accountID); - /** * Send a SIP message to a call identified by its callid * - * @param The InstantMessaging module which contains formating, parsing and sending method + * @param The InstantMessaging module which contains formating, parsing and sending method * @param The Id of the call to send the message to * @param The actual message to be transmitted * @param The sender of this message (could be another participant of a conference) @@ -408,11 +411,21 @@ class SIPVoIPLink : public VoIPLink */ bool sendTextMessage (sfl::InstantMessaging *module, const std::string& callID, const std::string& message, const std::string& from); - + /** + * Retrieve display name from the + */ static std::string parseDisplayName(char *); + /** + * Remove the "sip:" or "sips:" from input uri + */ static void stripSipUriPrefix(std::string&); + /** + * when we init the listener, how many times we try to bind a port? + */ + int _nbTryListenAddr; + private: /** * Constructor @@ -423,16 +436,7 @@ class SIPVoIPLink : public VoIPLink /* The singleton instance */ static SIPVoIPLink* _instance; - /** - * Enable the SIP SRV resolver - * @param endpt The SIP endpoint - * @param p_resv Pointer to receive The DNS resolver instance - * - * @return pj_status_t PJ_SUCCESS on success - */ - pj_status_t enable_dns_srv_resolver (pjsip_endpoint *endpt, pj_dns_resolver ** p_resv); - - void busy_sleep (unsigned msec); + void busySleep (unsigned msec); /** * Initialize the PJSIP library @@ -440,13 +444,16 @@ class SIPVoIPLink : public VoIPLink * * @return bool True on success */ - bool pjsip_init(); + bool pjsipInit(); /** * Delete link-related stuff like calls */ bool pjsip_shutdown (void); + /** + * Resolve public address for this account + */ pj_status_t stunServerResolve (AccountID id); @@ -522,40 +529,50 @@ class SIPVoIPLink : public VoIPLink */ pj_status_t createAlternateUdpTransport (AccountID id); + /** + * Get the correct address to use (ie advertised) from + * a uri. The corresponding transport that should be used + * with that uri will be discovered. + * + * @param uri The uri from which we want to discover the address to use + * @param transport The transport to use to discover the address + * @return pj_str_t The extern (public) address + */ + std::string findLocalAddressFromUri (const std::string& uri, pjsip_transport *transport); + + /* + * Does the same as findLocalAddressFromUri but returns a port. + * @param uri The uri from which we want to discover the port to use + * @param transport The transport to use to discover the port + * @return int The extern (public) port + */ + int findLocalPortFromUri (const std::string& uri, pjsip_transport *transport); + /** * UDP Transports are stored in this map in order to retreive them in case * several accounts would share the same port number. */ SipTransportMap _transportMap; - /** For registration use only */ + /** + * For registration use only + */ int _regPort; - /** Threading object */ + /** + * Threading object + */ EventThread* _evThread; - ost::Mutex _mutexSIP; - - /* Number of SIP accounts connected to the link */ - int _clients; - /* - * Get the correct address to use (ie advertised) from - * a uri. The corresponding transport that should be used - * with that uri will be discovered. - * - * @param uri The uri from which we want to discover the address to use - * @param transport The transport to use to discover the address - * @return pj_str_t The extern (public) address - */ - std::string findLocalAddressFromUri (const std::string& uri, pjsip_transport *transport); + /** + * Global mutex for the sip voiplink + */ + ost::Mutex _mutexSIP; - /* - * Does the same as findLocalAddressFromUri but returns a port. - * @param uri The uri from which we want to discover the port to use - * @param transport The transport to use to discover the port - * @return int The extern (public) port + /** + * Number of SIP accounts connected to the link */ - int findLocalPortFromUri (const std::string& uri, pjsip_transport *transport); + int _clients; friend class SIPTest; diff --git a/sflphone-common/src/voiplink.h b/sflphone-common/src/voiplink.h index 4f09d416516b897bf6dd9aa3d2326d53f6401b0e..0dbe51e9423d2be08f9cc953915abe081f604f39 100644 --- a/sflphone-common/src/voiplink.h +++ b/sflphone-common/src/voiplink.h @@ -45,6 +45,22 @@ typedef std::string AccountID; /** Define a map that associate a Call object to a call identifier */ typedef std::map<CallID, Call*> CallMap; +class VoipLinkException : public std::exception +{ + public: + VoipLinkException (const std::string& str="") throw() : errstr (str) {} + + virtual ~VoipLinkException() throw() {} + + virtual const char *what() const throw() { + std::string expt ("UserAgent: VoipLinkException occured: "); + expt.append (errstr); + return expt.c_str(); + } + private: + std::string errstr; +}; + /** * @file voiplink.h * @brief Listener and manager interface for each VoIP protocol @@ -111,7 +127,7 @@ class VoIPLink * @param toUrl The address of the recipient of the call * @return Call* The current call */ - virtual Call* newOutgoingCall (const CallID& id, const std::string& toUrl) = 0; + virtual Call* newOutgoingCall (const CallID& id, const std::string& toUrl) throw (VoipLinkException) = 0; /** * Answer the call