Merge branch 'master' of git+ssh://git.sflphone.org/var/repos/sflphone/git/sflphone

Conflicts:
	daemon/src/sip/sipvoiplink.cpp
This commit is contained in:
Alexandre Savard
2012-01-29 13:53:42 -05:00
25 changed files with 395 additions and 391 deletions

View File

@ -38,7 +38,6 @@ Account::Account(const std::string& accountID, const std::string &type) :
, username_()
, hostname_()
, alias_()
, link_(NULL)
, enabled_(true)
, type_(type)
, registrationState_(Unregistered)

View File

@ -71,7 +71,7 @@ static const char *const CONFIG_ACCOUNT_TYPE = "Account.type";
static const char *const CONFIG_ACCOUNT_ALIAS = "Account.alias";
static const char *const CONFIG_ACCOUNT_MAILBOX = "Account.mailbox";
static const char *const CONFIG_ACCOUNT_ENABLE = "Account.enable";
static const char *const CONFIG_ACCOUNT_REGISTRATION_EXPIRE = "Account.expire";
static const char *const CONFIG_ACCOUNT_REGISTRATION_EXPIRE = "Account.registrationExpire";
static const char *const CONFIG_CREDENTIAL_NUMBER = "Credential.count";
static const char *const ACCOUNT_DTMF_TYPE = "Account.dtmfType";
static const char *const CONFIG_RINGTONE_PATH = "Account.ringtonePath";
@ -188,9 +188,7 @@ class Account : public Serializable {
* Get the voiplink pointer
* @return VoIPLink* the pointer or 0
*/
VoIPLink* getVoIPLink() {
return link_;
}
virtual VoIPLink* getVoIPLink() = 0;
/**
* Register the underlying VoIPLink. Launch the event listener.
@ -324,11 +322,6 @@ class Account : public Serializable {
*/
std::string alias_;
/**
* Voice over IP Link contains a listener thread and calls
*/
VoIPLink* link_;
/**
* Tells if the link is enabled, active.
* This implies the link will be initialized on startup.

View File

@ -155,7 +155,7 @@ std::vector<sfl::Codec*> AudioCodecFactory::scanCodecDirectory()
if (envDir)
dirToScan.push_back(std::string(envDir) + DIR_SEPARATOR_STR);
const char *progDir = get_program_dir();
const char *progDir = fileutils::get_program_dir();
if (progDir)
dirToScan.push_back(std::string(progDir) + DIR_SEPARATOR_STR + "audio/codecs/");

View File

@ -190,7 +190,7 @@
<tp:docstring>
Send account registration (REGISTER) to the registrar.
</tp:docstring>
the account if expire=1, unregister if expire=0.
Register the account if enable=true, unregister if enable=false.
@param[in] input accountID
-->
@ -199,10 +199,10 @@
The account ID
</tp:docstring>
</arg>
<arg type="i" name="expire" direction="in">
<arg type="b" name="enable" direction="in">
<tp:docstring>
<p>To register, expire must be 1.</p>
<p>To un-register, expire must be 0.</p>
<p>To register, enable must be true.</p>
<p>To un-register, enable must be false.</p>
</tp:docstring>
</arg>
</method>

View File

@ -131,9 +131,9 @@ void ConfigurationManager::setAccountDetails(const std::string& accountID, const
Manager::instance().setAccountDetails(accountID, details);
}
void ConfigurationManager::sendRegister(const std::string& accountID, const int32_t& expire)
void ConfigurationManager::sendRegister(const std::string& accountID, const bool& enable)
{
Manager::instance().sendRegister(accountID, expire);
Manager::instance().sendRegister(accountID, enable);
}
std::string ConfigurationManager::addAccount(const std::map<std::string, std::string>& details)

View File

@ -68,7 +68,7 @@ class ConfigurationManager :
void removeAccount(const std::string& accoundID);
void deleteAllCredential(const std::string& accountID);
std::vector< std::string > getAccountList();
void sendRegister(const std::string& accoundID, const int32_t& expire);
void sendRegister(const std::string& accoundID, const bool& enable);
std::map< std::string, std::string > getTlsSettingsDefault();

View File

@ -31,6 +31,7 @@
#include <libgen.h>
#include <cstdlib>
namespace fileutils {
static char *program_dir = NULL;
void set_program_dir(char *program_path)
@ -42,3 +43,5 @@ const char *get_program_dir()
{
return program_dir;
}
}

View File

@ -31,7 +31,9 @@
#ifndef __FILEUTILS_H__
#define __FILEUTILS_H__
void set_program_dir(char *program_path);
const char *get_program_dir();
namespace fileutils {
void set_program_dir(char *program_path);
const char *get_program_dir();
}
#endif // __FILEUTILS_H__

View File

@ -38,10 +38,9 @@
#include "manager.h"
IAXAccount::IAXAccount(const std::string& accountID)
: Account(accountID, "iax2"), password_()
{
link_ = new IAXVoIPLink(accountID);
}
: Account(accountID, "iax2"), password_(),
link_(new IAXVoIPLink(accountID))
{}
IAXAccount::~IAXAccount()
@ -160,7 +159,7 @@ IAXAccount::unregisterVoIPLink()
{
try {
link_->sendUnregister(this);
dynamic_cast<IAXVoIPLink*>(link_)->terminate();
link_->terminate();
} catch (const VoipLinkException &e) {
ERROR("IAXAccount: %s", e.what());
}
@ -174,3 +173,8 @@ IAXAccount::loadConfig()
enabled_ = false;
#endif
}
VoIPLink* IAXAccount::getVoIPLink()
{
return link_;
}

View File

@ -32,6 +32,9 @@
#define IAXACCOUNT_H
#include "account.h"
#include "noncopyable.h"
class IAXVoIPLink;
/**
* @file: iaxaccount.h
@ -64,8 +67,11 @@ class IAXAccount : public Account {
}
private:
NON_COPYABLE(IAXAccount);
// Account login information: password
std::string password_;
IAXVoIPLink *link_;
virtual VoIPLink* getVoIPLink();
};
#endif

View File

@ -78,7 +78,7 @@ static bool check_dir(const char *path)
int
main(int argc, char **argv)
{
set_program_dir(argv[0]);
fileutils::set_program_dir(argv[0]);
// makeCommandOptionParse allocates the object with operator new, so
// auto_ptr is fine in this context.
// TODO: This should eventually be replaced with std::unique_ptr for C++0x

View File

@ -410,10 +410,10 @@ class ManagerImpl {
* ConfigurationManager - Send registration request
* @param accountId The account to register/unregister
* @param enable The flag for the type of registration
* 0 for unregistration request
* 1 for registration request
* false for unregistration request
* true for registration request
*/
void sendRegister(const std::string& accountId , const int32_t& enable);
void sendRegister(const std::string& accountId, bool enable);
/**
* Get account list

View File

@ -73,7 +73,7 @@ VoIPLink* ManagerImpl::getAccountLink(const std::string& accountID)
void
ManagerImpl::sendRegister(const std::string& accountID , const int32_t& enable)
ManagerImpl::sendRegister(const std::string& accountID, bool enable)
{
Account* acc = getAccount(accountID);

View File

@ -41,13 +41,17 @@
const char * const SIPAccount::OVERRTP_STR = "overrtp";
const char * const SIPAccount::SIPINFO_STR = "sipinfo";
namespace {
const int MIN_REGISTRATION_TIME = 600;
}
SIPAccount::SIPAccount(const std::string& accountID)
: Account(accountID, "SIP")
, transport_(NULL)
, credentials_()
, regc_(NULL)
, bRegister_(false)
, registrationExpire_(600)
, registrationExpire_(MIN_REGISTRATION_TIME)
, interface_("default")
, publishedSameasLocal_(true)
, publishedIpAddress_()
@ -88,13 +92,12 @@ SIPAccount::SIPAccount(const std::string& accountID)
, zrtpNotSuppWarning_(true)
, registrationStateDetailed_()
, keepAliveTimer_()
{
link_ = SIPVoIPLink::instance();
}
, link_(SIPVoIPLink::instance())
{}
SIPAccount::~SIPAccount()
{
delete[] cred_;
delete [] cred_;
}
void SIPAccount::serialize(Conf::YamlEmitter *emitter)
@ -111,9 +114,9 @@ void SIPAccount::serialize(Conf::YamlEmitter *emitter)
ScalarNode hostname(Account::hostname_);
ScalarNode enable(enabled_);
ScalarNode type(Account::type_);
std::stringstream expirevalstr;
expirevalstr << registrationExpire_;
ScalarNode expire(expirevalstr);
std::stringstream registrationExpireStr;
registrationExpireStr << registrationExpire_;
ScalarNode expire(registrationExpireStr);
ScalarNode interface(interface_);
std::stringstream portstr;
portstr << localPort_;
@ -171,7 +174,7 @@ void SIPAccount::serialize(Conf::YamlEmitter *emitter)
accountmap.setKeyValue(hostnameKey, &hostname);
accountmap.setKeyValue(accountEnableKey, &enable);
accountmap.setKeyValue(mailboxKey, &mailbox);
accountmap.setKeyValue(expireKey, &expire);
accountmap.setKeyValue(registrationExpireKey, &expire);
accountmap.setKeyValue(interfaceKey, &interface);
accountmap.setKeyValue(portKey, &port);
accountmap.setKeyValue(stunServerKey, &stunServer);
@ -244,7 +247,7 @@ void SIPAccount::serialize(Conf::YamlEmitter *emitter)
delete node;
}
}
void SIPAccount::unserialize(Conf::MappingNode *map)
@ -268,7 +271,7 @@ void SIPAccount::unserialize(Conf::MappingNode *map)
map->getValue(ringtonePathKey, &ringtonePath_);
map->getValue(ringtoneEnabledKey, &ringtoneEnabled_);
map->getValue(expireKey, &registrationExpire_);
map->getValue(registrationExpireKey, &registrationExpire_);
map->getValue(interfaceKey, &interface_);
int port;
map->getValue(portKey, &port);
@ -404,7 +407,6 @@ void SIPAccount::setAccountDetails(std::map<std::string, std::string> details)
stunServer_ = details[STUN_SERVER];
stunEnabled_ = details[STUN_ENABLE] == "true";
dtmfType_ = details[ACCOUNT_DTMF_TYPE];
registrationExpire_ = atoi(details[CONFIG_ACCOUNT_REGISTRATION_EXPIRE].c_str());
userAgent_ = details[USERAGENT];
@ -488,9 +490,9 @@ std::map<std::string, std::string> SIPAccount::getAccountDetails() const
a[ROUTESET] = serviceRoute_;
a[USERAGENT] = userAgent_;
std::stringstream expireval;
expireval << registrationExpire_;
a[CONFIG_ACCOUNT_REGISTRATION_EXPIRE] = expireval.str();
std::stringstream registrationExpireStr;
registrationExpireStr << registrationExpire_;
a[CONFIG_ACCOUNT_REGISTRATION_EXPIRE] = registrationExpireStr.str();
a[LOCAL_INTERFACE] = interface_;
a[PUBLISHED_SAMEAS_LOCAL] = publishedSameasLocal_ ? "true" : "false";
a[PUBLISHED_ADDRESS] = publishedIpAddress_;
@ -580,28 +582,27 @@ void SIPAccount::unregisterVoIPLink()
}
void SIPAccount::startKeepAliveTimer() {
pj_time_val keepAliveDelay_;
if (isTlsEnabled())
return;
pj_time_val keepAliveDelay_;
keepAliveTimer_.cb = &SIPAccount::keepAliveRegistrationCb;
keepAliveTimer_.user_data = (void *)this;
keepAliveTimer_.user_data = this;
// expiration may no be determined when during the first registration request
if(registrationExpire_ == 0) {
// expiration may be undetermined during the first registration request
if (registrationExpire_ == 0)
keepAliveDelay_.sec = 60;
}
else {
else
keepAliveDelay_.sec = registrationExpire_;
}
keepAliveDelay_.msec = 0;
reinterpret_cast<SIPVoIPLink *>(link_)->registerKeepAliveTimer(keepAliveTimer_, keepAliveDelay_);
link_->registerKeepAliveTimer(keepAliveTimer_, keepAliveDelay_);
}
void SIPAccount::stopKeepAliveTimer() {
reinterpret_cast<SIPVoIPLink *>(link_)->cancelKeepAliveTimer(keepAliveTimer_);
link_->cancelKeepAliveTimer(keepAliveTimer_);
}
pjsip_ssl_method SIPAccount::sslMethodStringToPjEnum(const std::string& method)
@ -669,7 +670,7 @@ void SIPAccount::initStunConfiguration()
void SIPAccount::loadConfig()
{
if (registrationExpire_ == 0)
registrationExpire_ = 600; /** Default expire value for registration */
registrationExpire_ = MIN_REGISTRATION_TIME; /** Default expire value for registration */
if (tlsEnable_ == "true") {
initTlsConfiguration();
@ -794,8 +795,7 @@ std::string SIPAccount::getContactHeader() const
// Else we determine this infor based on transport information
std::string address, port;
SIPVoIPLink *siplink = dynamic_cast<SIPVoIPLink *>(link_);
siplink->findLocalAddressFromTransport(transport_, transportType_, address, port);
link_->findLocalAddressFromTransport(transport_, transportType_, address, port);
// UDP does not require the transport specification
if (transportType_ == PJSIP_TRANSPORT_TLS) {
@ -821,7 +821,7 @@ void SIPAccount::keepAliveRegistrationCb(UNUSED pj_timer_heap_t *th, pj_timer_en
// send a new register request
sipAccount->registerVoIPLink();
// make sure the current timer is deactivated
// make sure the current timer is deactivated
sipAccount->stopKeepAliveTimer();
// register a new timer
@ -1036,3 +1036,8 @@ void SIPAccount::setTlsSettings(const std::map<std::string, std::string>& detail
set_opt(details, TLS_NEGOTIATION_TIMEOUT_SEC, tlsNegotiationTimeoutSec_);
set_opt(details, TLS_NEGOTIATION_TIMEOUT_MSEC, tlsNegotiationTimeoutMsec_);
}
VoIPLink* SIPAccount::getVoIPLink()
{
return link_;
}

View File

@ -47,7 +47,6 @@ namespace Conf {
class YamlEmitter;
class MappingNode;
// SIP specific configuration keys
const char *const expireKey = "expire";
const char *const interfaceKey = "interface";
const char *const portKey = "port";
const char *const publishAddrKey = "publishAddr";
@ -114,6 +113,9 @@ class SIPAccount : public Account {
* Virtual destructor
*/
virtual ~SIPAccount();
virtual VoIPLink* getVoIPLink();
std::string getUserAgentName() const;
void setRegistrationStateDetailed(const std::pair<int, std::string> &details) {
registrationStateDetailed_ = details;
@ -224,7 +226,7 @@ class SIPAccount : public Account {
* the "Expire" sip header or the CONTACT's "expire" param.
*/
void setRegistrationExpire(int expire) {
if(expire > 0)
if (expire > 0)
registrationExpire_ = expire;
}
@ -693,6 +695,11 @@ class SIPAccount : public Account {
*/
pj_timer_entry keepAliveTimer_;
/**
* Voice over IP Link contains a listener thread and calls
*/
SIPVoIPLink* link_;
};
#endif

View File

@ -94,7 +94,7 @@ void setCallMediaLocal(SIPCall* call, const std::string &localIP);
/**
* Helper function to parser header from incoming sip messages
*/
std::string fetchHeaderValue(pjsip_msg *msg, std::string field);
std::string fetchHeaderValue(pjsip_msg *msg, const std::string &field);
static pj_caching_pool pool_cache, *cp_ = &pool_cache;
static pj_pool_t *pool_;
@ -102,17 +102,17 @@ static pjsip_endpoint *endpt_;
static pjsip_module mod_ua_;
static pj_thread_t *thread;
static void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status UNUSED);
static void sdp_request_offer_cb(pjsip_inv_session *inv, const pjmedia_sdp_session *offer);
static void sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer);
static void invite_session_state_changed_cb(pjsip_inv_session *inv, pjsip_event *e);
static void outgoing_request_forked_cb(pjsip_inv_session *inv, pjsip_event *e);
static void transaction_state_changed_cb(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e);
static void registration_cb(pjsip_regc_cbparam *param);
static pj_bool_t transaction_request_cb(pjsip_rx_data *rdata);
static pj_bool_t transaction_response_cb(pjsip_rx_data *rdata UNUSED) ;
void sdp_media_update_cb(pjsip_inv_session *inv, pj_status_t status UNUSED);
void sdp_request_offer_cb(pjsip_inv_session *inv, const pjmedia_sdp_session *offer);
void sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer);
void invite_session_state_changed_cb(pjsip_inv_session *inv, pjsip_event *e);
void outgoing_request_forked_cb(pjsip_inv_session *inv, pjsip_event *e);
void transaction_state_changed_cb(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e);
void registration_cb(pjsip_regc_cbparam *param);
pj_bool_t transaction_request_cb(pjsip_rx_data *rdata);
pj_bool_t transaction_response_cb(pjsip_rx_data *rdata UNUSED) ;
static void transfer_client_cb(pjsip_evsub *sub, pjsip_event *event);
void transfer_client_cb(pjsip_evsub *sub, pjsip_event *event);
/**
* Send a reINVITE inside an active dialog to modify its state
@ -163,6 +163,274 @@ pjsip_route_hdr *createRouteSet(const std::string &route, pj_pool_t *hdr_pool)
return route_set;
}
void handleIncomingOptions(pjsip_rx_data *rdata)
{
pjsip_tx_data *tdata;
if (pjsip_endpt_create_response(endpt_, rdata, PJSIP_SC_OK, NULL, &tdata) != PJ_SUCCESS)
return;
#define ADD_HDR(hdr) do { \
const pjsip_hdr *cap_hdr = hdr; \
if (cap_hdr) \
pjsip_msg_add_hdr (tdata->msg, (pjsip_hdr*) pjsip_hdr_clone (tdata->pool, cap_hdr)); \
} while(0)
#define ADD_CAP(cap) ADD_HDR(pjsip_endpt_get_capability(endpt_, cap, NULL));
ADD_CAP(PJSIP_H_ALLOW);
ADD_CAP(PJSIP_H_ACCEPT);
ADD_CAP(PJSIP_H_SUPPORTED);
ADD_HDR(pjsip_evsub_get_allow_events_hdr(NULL));
pjsip_response_addr res_addr;
pjsip_get_response_addr(tdata->pool, rdata, &res_addr);
if (pjsip_endpt_send_response(endpt_, &res_addr, tdata, NULL, NULL) != PJ_SUCCESS)
pjsip_tx_data_dec_ref(tdata);
}
pj_bool_t transaction_response_cb(pjsip_rx_data *rdata)
{
pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
if (!dlg)
return PJ_SUCCESS;
pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
if (!tsx or tsx->method.id != PJSIP_INVITE_METHOD)
return PJ_SUCCESS;
if (tsx->status_code / 100 == 2) {
/**
* Send an ACK message inside a transaction. PJSIP send automatically, non-2xx ACK response.
* ACK for a 2xx response must be send using this method.
*/
pjsip_tx_data *tdata;
pjsip_dlg_create_request(dlg, &pjsip_ack_method, rdata->msg_info.cseq->cseq, &tdata);
pjsip_dlg_send_request(dlg, tdata, -1, NULL);
}
return PJ_SUCCESS;
}
std::string parseDisplayName(const char * buffer)
{
const char* from_header = strstr(buffer, "From: ");
if (!from_header)
return "";
std::string temp(from_header);
size_t begin_displayName = temp.find("\"") + 1;
size_t end_displayName = temp.rfind("\"");
std::string displayName(temp.substr(begin_displayName, end_displayName - begin_displayName));
static const size_t MAX_DISPLAY_NAME_SIZE = 25;
if (displayName.size() > MAX_DISPLAY_NAME_SIZE)
return "";
return displayName;
}
void stripSipUriPrefix(std::string& sipUri)
{
// Remove sip: prefix
static const char SIP_PREFIX[] = "sip:";
size_t found = sipUri.find(SIP_PREFIX);
if (found != std::string::npos)
sipUri.erase(found, found + (sizeof SIP_PREFIX) - 1);
found = sipUri.find("@");
if (found != std::string::npos)
sipUri.erase(found);
}
pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
{
pjsip_method *method = &rdata->msg_info.msg->line.req.method;
if (method->id == PJSIP_ACK_METHOD && pjsip_rdata_get_dlg(rdata))
return true;
pjsip_sip_uri *sip_to_uri = (pjsip_sip_uri *) pjsip_uri_get_uri(rdata->msg_info.to->uri);
pjsip_sip_uri *sip_from_uri = (pjsip_sip_uri *) pjsip_uri_get_uri(rdata->msg_info.from->uri);
std::string userName(sip_to_uri->user.ptr, sip_to_uri->user.slen);
std::string server(sip_from_uri->host.ptr, sip_from_uri->host.slen);
std::string account_id(Manager::instance().getAccountIdFromNameAndServer(userName, server));
std::string displayName(parseDisplayName(rdata->msg_info.msg_buf));
if (method->id == PJSIP_OTHER_METHOD) {
pj_str_t *str = &method->name;
std::string request(str->ptr, str->slen);
if (request.find("NOTIFY") != (size_t)-1) {
int voicemail;
if (sscanf((const char*)rdata->msg_info.msg->body->data, "Voice-Message: %d/", &voicemail) == 1 && voicemail != 0)
Manager::instance().startVoiceMessageNotification(account_id, voicemail);
}
pjsip_endpt_respond_stateless(endpt_, rdata, PJSIP_SC_OK, NULL, NULL, NULL);
return true;
} else if (method->id == PJSIP_OPTIONS_METHOD) {
handleIncomingOptions(rdata);
return true;
} else if (method->id != PJSIP_INVITE_METHOD && method->id != PJSIP_ACK_METHOD) {
pjsip_endpt_respond_stateless(endpt_, rdata, PJSIP_SC_METHOD_NOT_ALLOWED, NULL, NULL, NULL);
return true;
}
SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(account_id));
pjmedia_sdp_session *r_sdp;
pjsip_msg_body *body = rdata->msg_info.msg->body;
if (!body || pjmedia_sdp_parse(rdata->tp_info.pool, (char*) body->data, body->len, &r_sdp) != PJ_SUCCESS)
r_sdp = NULL;
if (account->getActiveCodecs().empty()) {
pjsip_endpt_respond_stateless(endpt_, rdata,
PJSIP_SC_NOT_ACCEPTABLE_HERE, NULL, NULL,
NULL);
return false;
}
// Verify that we can handle the request
unsigned options = 0;
if (pjsip_inv_verify_request(rdata, &options, NULL, NULL, endpt_, NULL) != PJ_SUCCESS) {
pjsip_endpt_respond_stateless(endpt_, rdata, PJSIP_SC_METHOD_NOT_ALLOWED, NULL, NULL, NULL);
return true;
}
if (Manager::instance().hookPreference.getSipEnabled()) {
std::string header_value(fetchHeaderValue(rdata->msg_info.msg, Manager::instance().hookPreference.getUrlSipField()));
UrlHook::runAction(Manager::instance().hookPreference.getUrlCommand(), header_value);
}
SIPCall* call = new SIPCall(Manager::instance().getNewCallID(), Call::INCOMING, cp_);
Manager::instance().associateCallToAccount(call->getCallId(), account_id);
// May use the published address as well
std::string addrToUse = SIPVoIPLink::instance()->getInterfaceAddrFromName(account->getLocalInterface());
std::string addrSdp = account->isStunEnabled()
? account->getPublishedAddress()
: addrToUse;
pjsip_tpselector *tp = SIPVoIPLink::instance()->initTransportSelector(account->transport_, call->getMemoryPool());
if (addrToUse == "0.0.0.0")
addrToUse = getSIPLocalIP();
if (addrSdp == "0.0.0.0")
addrSdp = addrToUse;
char tmp[PJSIP_MAX_URL_SIZE];
int length = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, sip_from_uri, tmp, PJSIP_MAX_URL_SIZE);
std::string peerNumber(tmp, length);
stripSipUriPrefix(peerNumber);
call->setConnectionState(Call::PROGRESSING);
call->setPeerNumber(peerNumber);
call->setDisplayName(displayName);
call->initRecFilename(peerNumber);
setCallMediaLocal(call, addrToUse);
call->getLocalSDP()->setLocalIP(addrSdp);
call->getAudioRtp().initAudioRtpConfig();
call->getAudioRtp().initAudioSymmetricRtpSession();
if (rdata->msg_info.msg->body) {
char sdpbuffer[1000];
int len = rdata->msg_info.msg->body->print_body(rdata->msg_info.msg->body, sdpbuffer, sizeof sdpbuffer);
if (len == -1) // error
len = 0;
std::string sdpoffer(sdpbuffer, len);
size_t start = sdpoffer.find("a=crypto:");
// Found crypto header in SDP
if (start != std::string::npos) {
CryptoOffer crypto_offer;
crypto_offer.push_back(std::string(sdpoffer.substr(start, (sdpoffer.size() - start) - 1)));
std::vector<sfl::CryptoSuiteDefinition>localCapabilities;
for (int i = 0; i < 3; i++)
localCapabilities.push_back(sfl::CryptoSuites[i]);
sfl::SdesNegotiator sdesnego(localCapabilities, crypto_offer);
if (sdesnego.negotiate()) {
call->getAudioRtp().setRemoteCryptoInfo(sdesnego);
call->getAudioRtp().initLocalCryptoInfo();
}
}
}
call->getLocalSDP()->receiveOffer(r_sdp, account->getActiveCodecs());
sfl::Codec* audiocodec = Manager::instance().audioCodecFactory.instantiateCodec(PAYLOAD_CODEC_ULAW);
call->getAudioRtp().start(static_cast<sfl::AudioCodec *>(audiocodec));
pjsip_dialog* dialog;
if (pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, NULL, &dialog) != PJ_SUCCESS) {
delete call;
pjsip_endpt_respond_stateless(endpt_, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL, NULL);
return false;
}
pjsip_inv_create_uas(dialog, rdata, call->getLocalSDP()->getLocalSdpSession(), 0, &call->inv);
PJ_ASSERT_RETURN(pjsip_dlg_set_transport(dialog, tp) == PJ_SUCCESS, 1);
call->inv->mod_data[mod_ua_.id] = call;
// Check whether Replaces header is present in the request and process accordingly.
pjsip_dialog *replaced_dlg;
pjsip_tx_data *response;
if (pjsip_replaces_verify_request(rdata, &replaced_dlg, PJ_FALSE, &response) != PJ_SUCCESS) {
ERROR("Something wrong with Replaces request.");
pjsip_endpt_respond_stateless(endpt_, rdata, 500 /* internal server error */, NULL, NULL, NULL);
}
// Check if call has been transfered
pjsip_tx_data *tdata;
if (replaced_dlg) { // If Replace header present
// Always answer the new INVITE with 200, regardless whether
// the replaced call is in early or confirmed state.
if (pjsip_inv_answer(call->inv, 200, NULL, NULL, &response) == PJ_SUCCESS)
pjsip_inv_send_msg(call->inv, response);
// Get the INVITE session associated with the replaced dialog.
pjsip_inv_session *replaced_inv = pjsip_dlg_get_inv_session(replaced_dlg);
// Disconnect the "replaced" INVITE session.
if (pjsip_inv_end_session(replaced_inv, PJSIP_SC_GONE, NULL, &tdata) == PJ_SUCCESS && tdata)
pjsip_inv_send_msg(replaced_inv, tdata);
} else { // Prooceed with normal call flow
PJ_ASSERT_RETURN(pjsip_inv_initial_answer(call->inv, rdata, PJSIP_SC_RINGING, NULL, NULL, &tdata) == PJ_SUCCESS, 1);
PJ_ASSERT_RETURN(pjsip_inv_send_msg(call->inv, tdata) == PJ_SUCCESS, 1);
call->setConnectionState(Call::RINGING);
Manager::instance().incomingCall(call, account_id);
Manager::instance().getAccountLink(account_id)->addCall(call);
}
return true;
}
} // end anonymous namespace
/*************************************************************************************************/
@ -170,9 +438,9 @@ pjsip_route_hdr *createRouteSet(const std::string &route, pj_pool_t *hdr_pool)
SIPVoIPLink::SIPVoIPLink() : transportMap_(), evThread_(new EventThread(this))
{
#define TRY(ret) do { \
if (ret != PJ_SUCCESS) \
throw VoipLinkException(#ret " failed"); \
} while(0)
if (ret != PJ_SUCCESS) \
throw VoipLinkException(#ret " failed"); \
} while(0)
srand(time(NULL)); // to get random number for RANDOM_PORT
@ -389,9 +657,8 @@ void SIPVoIPLink::registerKeepAliveTimer(pj_timer_entry& timer, pj_time_val& del
pj_status_t status;
status = pjsip_endpt_schedule_timer(endpt_, &timer, &delay);
if(status != PJ_SUCCESS) {
if (status != PJ_SUCCESS)
ERROR("Could not schedule new timer in pjsip endpoint");
}
}
void SIPVoIPLink::cancelKeepAliveTimer(pj_timer_entry& timer)
@ -975,12 +1242,12 @@ bool SIPVoIPLink::SIPNewIpToIpCall(const std::string& id, const std::string& to)
// Private functions
///////////////////////////////////////////////////////////////////////////////
static pj_bool_t stun_sock_on_status_cb(pj_stun_sock *stun_sock UNUSED, pj_stun_sock_op op UNUSED, pj_status_t status)
pj_bool_t stun_sock_on_status_cb(pj_stun_sock *stun_sock UNUSED, pj_stun_sock_op op UNUSED, pj_status_t status)
{
return status == PJ_SUCCESS;
}
static pj_bool_t stun_sock_on_rx_data_cb(pj_stun_sock *stun_sock UNUSED, void *pkt UNUSED, unsigned pkt_len UNUSED, const pj_sockaddr_t *src_addr UNUSED, unsigned addr_len UNUSED)
pj_bool_t stun_sock_on_rx_data_cb(pj_stun_sock *stun_sock UNUSED, void *pkt UNUSED, unsigned pkt_len UNUSED, const pj_sockaddr_t *src_addr UNUSED, unsigned addr_len UNUSED)
{
return PJ_TRUE;
}
@ -1223,7 +1490,7 @@ void SIPVoIPLink::findLocalAddressFromTransport(pjsip_transport *transport, pjsi
addr = std::string(pjMachineName->ptr, pjMachineName->slen);
// Update address and port with active transport
if(!transport) {
if (!transport) {
ERROR("SIPVoIPLink: Transport is NULL in findLocalAddress, using local address %s:%s", addr.c_str(), port.c_str());
return;
}
@ -1239,11 +1506,10 @@ void SIPVoIPLink::findLocalAddressFromTransport(pjsip_transport *transport, pjsi
// TODO Need to determine why we exclude TLS here...
// if (transportType == PJSIP_TRANSPORT_UDP and transport_)
pjsip_tpselector *tp_sel = initTransportSelector(transport, pool_);
if(!tp_sel) {
if (!tp_sel) {
ERROR("SIPVoIPLink: Could not initialize transport selector, using local address %s:%s", addr.c_str(), port.c_str());
return;
}
pj_str_t localAddress = {0,0};
int i_port = 0;
@ -1268,40 +1534,6 @@ void SIPVoIPLink::findLocalAddressFromTransport(pjsip_transport *transport, pjsi
}
namespace {
std::string parseDisplayName(const char * buffer)
{
const char* from_header = strstr(buffer, "From: ");
if (!from_header)
return "";
std::string temp(from_header);
size_t begin_displayName = temp.find("\"") + 1;
size_t end_displayName = temp.rfind("\"");
std::string displayName(temp.substr(begin_displayName, end_displayName - begin_displayName));
static const size_t MAX_DISPLAY_NAME_SIZE = 25;
if (displayName.size() > MAX_DISPLAY_NAME_SIZE)
return "";
return displayName;
}
void stripSipUriPrefix(std::string& sipUri)
{
// Remove sip: prefix
static const char SIP_PREFIX[] = "sip:";
size_t found = sipUri.find(SIP_PREFIX);
if (found != std::string::npos)
sipUri.erase(found, found + (sizeof SIP_PREFIX) - 1);
found = sipUri.find("@");
if (found != std::string::npos)
sipUri.erase(found);
}
int SIPSessionReinvite(SIPCall *call)
{
pjsip_tx_data *tdata;
@ -1386,7 +1618,7 @@ void sdp_request_offer_cb(pjsip_inv_session *inv, const pjmedia_sdp_session *off
pjsip_inv_set_sdp_answer(call->inv, call->getLocalSDP()->getLocalSdpSession());
}
static void sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer)
void sdp_create_offer_cb(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer)
{
SIPCall *call = reinterpret_cast<SIPCall*>(inv->mod_data[mod_ua_.id]);
std::string accountid(Manager::instance().getAccountFromCall(call->getCallId()));
@ -1612,11 +1844,8 @@ void transaction_state_changed_cb(pjsip_inv_session *inv UNUSED, pjsip_transacti
}
}
static void update_contact_header(struct pjsip_regc_cbparam *param, SIPAccount *account)
void update_contact_header(struct pjsip_regc_cbparam *param, SIPAccount *account)
{
pj_pool_t *pool = NULL;
pjsip_contact_hdr *contact_hdr = NULL;
pjsip_sip_uri *uri = NULL;
SIPVoIPLink *siplink = dynamic_cast<SIPVoIPLink *>(account->getVoIPLink());
if(siplink == NULL) {
@ -1624,39 +1853,36 @@ static void update_contact_header(struct pjsip_regc_cbparam *param, SIPAccount *
return;
}
pool = pj_pool_create(&cp_->factory, "tmp", 512, 512, NULL);
pj_pool_t *pool = pj_pool_create(&cp_->factory, "tmp", 512, 512, NULL);
if(pool == NULL) {
ERROR("SIPVoIPLink: Could not create temporary memory pool in transport header");
return;
}
if(param->contact_cnt == 0) {
if (param->contact_cnt == 0) {
WARN("SIPVoIPLink: No contact header in registration callback");
pj_pool_release(pool);
return;
}
contact_hdr = param->contact[0];
pjsip_contact_hdr *contact_hdr = param->contact[0];
uri = (pjsip_sip_uri*) contact_hdr->uri;
if(uri == NULL) {
pjsip_sip_uri *uri = (pjsip_sip_uri*) contact_hdr->uri;
if (uri == NULL) {
ERROR("SIPVoIPLink: Could not find uri in contact header");
pj_pool_release(pool);
return;
}
uri = (pjsip_sip_uri*) pjsip_uri_get_uri(uri);
if (uri->port == 0) {
// TODO: make this base on transport type
uri->port = 5060; //pjsip_transport_get_default_port_for_type(tp_type);
}
// TODO: make this based on transport type
// with pjsip_transport_get_default_port_for_type(tp_type);
if (uri->port == 0)
uri->port = DEFAULT_SIP_PORT;
std::string recvContactHost(uri->host.ptr, uri->host.slen);
std::stringstream ss;
ss << uri->port;
std::string recvContactPort = ss.str();
std::string currentAddress, currentPort;
siplink->findLocalAddressFromTransport(account->transport_, PJSIP_TRANSPORT_UDP, currentAddress, currentPort);
@ -1679,7 +1905,6 @@ static void update_contact_header(struct pjsip_regc_cbparam *param, SIPAccount *
account->setContactHeader(recvContactHost, recvContactPort);
siplink->sendRegister(account);
}
pj_pool_release(pool);
}
@ -1763,243 +1988,6 @@ void registration_cb(struct pjsip_regc_cbparam *param)
}
}
static void handleIncomingOptions(pjsip_rx_data *rdata)
{
pjsip_tx_data *tdata;
if (pjsip_endpt_create_response(endpt_, rdata, PJSIP_SC_OK, NULL, &tdata) != PJ_SUCCESS)
return;
#define ADD_HDR(hdr) do { \
const pjsip_hdr *cap_hdr = hdr; \
if (cap_hdr) \
pjsip_msg_add_hdr (tdata->msg, (pjsip_hdr*) pjsip_hdr_clone (tdata->pool, cap_hdr)); \
} while(0)
#define ADD_CAP(cap) ADD_HDR(pjsip_endpt_get_capability(endpt_, cap, NULL));
ADD_CAP(PJSIP_H_ALLOW);
ADD_CAP(PJSIP_H_ACCEPT);
ADD_CAP(PJSIP_H_SUPPORTED);
ADD_HDR(pjsip_evsub_get_allow_events_hdr(NULL));
pjsip_response_addr res_addr;
pjsip_get_response_addr(tdata->pool, rdata, &res_addr);
if (pjsip_endpt_send_response(endpt_, &res_addr, tdata, NULL, NULL) != PJ_SUCCESS)
pjsip_tx_data_dec_ref(tdata);
}
static pj_bool_t transaction_request_cb(pjsip_rx_data *rdata)
{
pjsip_method *method = &rdata->msg_info.msg->line.req.method;
if (method->id == PJSIP_ACK_METHOD && pjsip_rdata_get_dlg(rdata))
return true;
pjsip_sip_uri *sip_to_uri = (pjsip_sip_uri *) pjsip_uri_get_uri(rdata->msg_info.to->uri);
pjsip_sip_uri *sip_from_uri = (pjsip_sip_uri *) pjsip_uri_get_uri(rdata->msg_info.from->uri);
std::string userName(sip_to_uri->user.ptr, sip_to_uri->user.slen);
std::string server(sip_from_uri->host.ptr, sip_from_uri->host.slen);
std::string account_id(Manager::instance().getAccountIdFromNameAndServer(userName, server));
std::string displayName(parseDisplayName(rdata->msg_info.msg_buf));
if (method->id == PJSIP_OTHER_METHOD) {
pj_str_t *str = &method->name;
std::string request(str->ptr, str->slen);
if (request.find("NOTIFY") != (size_t)-1) {
int voicemail;
if (sscanf((const char*)rdata->msg_info.msg->body->data, "Voice-Message: %d/", &voicemail) == 1 && voicemail != 0)
Manager::instance().startVoiceMessageNotification(account_id, voicemail);
}
pjsip_endpt_respond_stateless(endpt_, rdata, PJSIP_SC_OK, NULL, NULL, NULL);
return true;
} else if (method->id == PJSIP_OPTIONS_METHOD) {
handleIncomingOptions(rdata);
return true;
} else if (method->id != PJSIP_INVITE_METHOD && method->id != PJSIP_ACK_METHOD) {
pjsip_endpt_respond_stateless(endpt_, rdata, PJSIP_SC_METHOD_NOT_ALLOWED, NULL, NULL, NULL);
return true;
}
SIPAccount *account = dynamic_cast<SIPAccount *>(Manager::instance().getAccount(account_id));
pjmedia_sdp_session *r_sdp;
pjsip_msg_body *body = rdata->msg_info.msg->body;
if (!body || pjmedia_sdp_parse(rdata->tp_info.pool, (char*) body->data, body->len, &r_sdp) != PJ_SUCCESS)
r_sdp = NULL;
if (account->getActiveCodecs().empty()) {
pjsip_endpt_respond_stateless(endpt_, rdata,
PJSIP_SC_NOT_ACCEPTABLE_HERE, NULL, NULL,
NULL);
return false;
}
// Verify that we can handle the request
unsigned options = 0;
if (pjsip_inv_verify_request(rdata, &options, NULL, NULL, endpt_, NULL) != PJ_SUCCESS) {
pjsip_endpt_respond_stateless(endpt_, rdata, PJSIP_SC_METHOD_NOT_ALLOWED, NULL, NULL, NULL);
return true;
}
if (Manager::instance().hookPreference.getSipEnabled()) {
std::string header_value(fetchHeaderValue(rdata->msg_info.msg, Manager::instance().hookPreference.getUrlSipField()));
UrlHook::runAction(Manager::instance().hookPreference.getUrlCommand(), header_value);
}
SIPCall* call = new SIPCall(Manager::instance().getNewCallID(), Call::INCOMING, cp_);
Manager::instance().associateCallToAccount(call->getCallId(), account_id);
// May use the published address as well
std::string addrToUse = SIPVoIPLink::instance()->getInterfaceAddrFromName(account->getLocalInterface());
std::string addrSdp = account->isStunEnabled()
? account->getPublishedAddress()
: addrToUse;
pjsip_tpselector *tp = SIPVoIPLink::instance()->initTransportSelector(account->transport_, call->getMemoryPool());
if (addrToUse == "0.0.0.0")
addrToUse = getSIPLocalIP();
if (addrSdp == "0.0.0.0")
addrSdp = addrToUse;
char tmp[PJSIP_MAX_URL_SIZE];
int length = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, sip_from_uri, tmp, PJSIP_MAX_URL_SIZE);
std::string peerNumber(tmp, length);
stripSipUriPrefix(peerNumber);
call->setConnectionState(Call::PROGRESSING);
call->setPeerNumber(peerNumber);
call->setDisplayName(displayName);
call->initRecFilename(peerNumber);
setCallMediaLocal(call, addrToUse);
call->getLocalSDP()->setLocalIP(addrSdp);
call->getAudioRtp().initAudioRtpConfig();
call->getAudioRtp().initAudioSymmetricRtpSession();
if (rdata->msg_info.msg->body) {
char sdpbuffer[1000];
int len = rdata->msg_info.msg->body->print_body(rdata->msg_info.msg->body, sdpbuffer, sizeof sdpbuffer);
if (len == -1) // error
len = 0;
std::string sdpoffer(sdpbuffer, len);
size_t start = sdpoffer.find("a=crypto:");
// Found crypto header in SDP
if (start != std::string::npos) {
CryptoOffer crypto_offer;
crypto_offer.push_back(std::string(sdpoffer.substr(start, (sdpoffer.size() - start) - 1)));
std::vector<sfl::CryptoSuiteDefinition>localCapabilities;
for (int i = 0; i < 3; i++)
localCapabilities.push_back(sfl::CryptoSuites[i]);
sfl::SdesNegotiator sdesnego(localCapabilities, crypto_offer);
if (sdesnego.negotiate()) {
call->getAudioRtp().setRemoteCryptoInfo(sdesnego);
call->getAudioRtp().initLocalCryptoInfo();
}
}
}
call->getLocalSDP()->receiveOffer(r_sdp, account->getActiveCodecs());
sfl::Codec* audiocodec = Manager::instance().audioCodecFactory.instantiateCodec(PAYLOAD_CODEC_ULAW);
call->getAudioRtp().start(static_cast<sfl::AudioCodec *>(audiocodec));
pjsip_dialog* dialog;
if (pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, NULL, &dialog) != PJ_SUCCESS) {
delete call;
pjsip_endpt_respond_stateless(endpt_, rdata, PJSIP_SC_INTERNAL_SERVER_ERROR, NULL, NULL, NULL);
return false;
}
pjsip_inv_create_uas(dialog, rdata, call->getLocalSDP()->getLocalSdpSession(), 0, &call->inv);
PJ_ASSERT_RETURN(pjsip_dlg_set_transport(dialog, tp) == PJ_SUCCESS, 1);
call->inv->mod_data[mod_ua_.id] = call;
// Check whether Replaces header is present in the request and process accordingly.
pjsip_dialog *replaced_dlg;
pjsip_tx_data *response;
if (pjsip_replaces_verify_request(rdata, &replaced_dlg, PJ_FALSE, &response) != PJ_SUCCESS) {
ERROR("Something wrong with Replaces request.");
pjsip_endpt_respond_stateless(endpt_, rdata, 500 /* internal server error */, NULL, NULL, NULL);
}
// Check if call has been transfered
pjsip_tx_data *tdata;
if (replaced_dlg) { // If Replace header present
// Always answer the new INVITE with 200, regardless whether
// the replaced call is in early or confirmed state.
if (pjsip_inv_answer(call->inv, 200, NULL, NULL, &response) == PJ_SUCCESS)
pjsip_inv_send_msg(call->inv, response);
// Get the INVITE session associated with the replaced dialog.
pjsip_inv_session *replaced_inv = pjsip_dlg_get_inv_session(replaced_dlg);
// Disconnect the "replaced" INVITE session.
if (pjsip_inv_end_session(replaced_inv, PJSIP_SC_GONE, NULL, &tdata) == PJ_SUCCESS && tdata)
pjsip_inv_send_msg(replaced_inv, tdata);
} else { // Prooceed with normal call flow
PJ_ASSERT_RETURN(pjsip_inv_initial_answer(call->inv, rdata, PJSIP_SC_RINGING, NULL, NULL, &tdata) == PJ_SUCCESS, 1);
PJ_ASSERT_RETURN(pjsip_inv_send_msg(call->inv, tdata) == PJ_SUCCESS, 1);
call->setConnectionState(Call::RINGING);
Manager::instance().incomingCall(call, account_id);
Manager::instance().getAccountLink(account_id)->addCall(call);
}
return true;
}
static pj_bool_t transaction_response_cb(pjsip_rx_data *rdata)
{
pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
if (!dlg)
return PJ_SUCCESS;
pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
if (!tsx or tsx->method.id != PJSIP_INVITE_METHOD)
return PJ_SUCCESS;
if (tsx->status_code / 100 == 2) {
/**
* Send an ACK message inside a transaction. PJSIP send automatically, non-2xx ACK response.
* ACK for a 2xx response must be send using this method.
*/
pjsip_tx_data *tdata;
pjsip_dlg_create_request(dlg, &pjsip_ack_method, rdata->msg_info.cseq->cseq, &tdata);
pjsip_dlg_send_request(dlg, tdata, -1, NULL);
}
return PJ_SUCCESS;
}
void onCallTransfered(pjsip_inv_session *inv, pjsip_rx_data *rdata)
{
SIPCall *currentCall = reinterpret_cast<SIPCall *>(inv->mod_data[mod_ua_.id]);
@ -2101,7 +2089,7 @@ void setCallMediaLocal(SIPCall* call, const std::string &localIP)
call->getLocalSDP()->setLocalPublishedAudioPort(callLocalExternAudioPort);
}
std::string fetchHeaderValue(pjsip_msg *msg, std::string field)
std::string fetchHeaderValue(pjsip_msg *msg, const std::string &field)
{
pj_str_t name = pj_str((char*) field.c_str());
@ -2119,7 +2107,6 @@ std::string fetchHeaderValue(pjsip_msg *msg, std::string field)
return value.substr(0, pos);
}
} // end anonymous namespace
std::vector<std::string> SIPVoIPLink::getAllIpInterfaceByName()

View File

@ -166,7 +166,7 @@ void ConfigurationTest::testYamlEmitter()
accountmap.setKeyValue(hostnameKey, &hostname);
accountmap.setKeyValue(accountEnableKey, &enable);
accountmap.setKeyValue(mailboxKey, &mailbox);
accountmap.setKeyValue(expireKey, &expire);
accountmap.setKeyValue(registrationExpireKey, &expire);
accountmap.setKeyValue(interfaceKey, &interface);
accountmap.setKeyValue(portKey, &port);
accountmap.setKeyValue(publishAddrKey, &publishAddr);

View File

@ -260,17 +260,15 @@ static void enable_account_cb(GtkCellRendererToggle *rend UNUSED, gchar* path,
// Modify account state
gchar * registrationState;
if (enable == TRUE) {
if (enable == TRUE)
registrationState = g_strdup("true");
} else {
else
registrationState = g_strdup("false");
}
DEBUG("Replacing with %s", registrationState);
g_hash_table_replace(acc->properties , g_strdup(ACCOUNT_ENABLED), registrationState);
dbus_send_register(acc->accountID, enable);
}
/**

View File

@ -1518,7 +1518,7 @@ static void menuitem_response(gchar *string)
dbus_join_participant(calltree_selected_call->_callID,
calltree_dragged_call->_callID);
else if (g_strcmp0(string, SFL_TRANSFER_CALL) == 0) {
DEBUG("Calltree: Transfering call %s, to %s",
DEBUG("Calltree: Transferring call %s, to %s",
calltree_selected_call->_peer_number,
calltree_dragged_call->_peer_number);
dbus_attended_transfer(calltree_selected_call, calltree_dragged_call);

View File

@ -190,7 +190,7 @@
<tp:docstring>
Send account registration (REGISTER) to the registrar.
</tp:docstring>
the account if expire=1, unregister if expire=0.
Register the account if enable=true, unregister if enable=false.
@param[in] input accountID
-->
@ -199,10 +199,10 @@
The account ID
</tp:docstring>
</arg>
<arg type="i" name="expire" direction="in">
<arg type="b" name="enable" direction="in">
<tp:docstring>
<p>To register, expire must be 1.</p>
<p>To un-register, expire must be 0.</p>
<p>To register, enable must be true.</p>
<p>To un-register, enable must be false.</p>
</tp:docstring>
</arg>
</method>

View File

@ -1030,7 +1030,7 @@ dbus_get_ip2_ip_details(void)
}
void
dbus_send_register(gchar* accountID, const guint enable)
dbus_send_register(gchar* accountID, gboolean enable)
{
GError *error = NULL;
org_sflphone_SFLphone_ConfigurationManager_send_register(

View File

@ -155,7 +155,7 @@ GHashTable * dbus_get_ip2_ip_details (void);
* 0 for unregistration request
* 1 for registration request
*/
void dbus_send_register (gchar* accountID , const guint enable);
void dbus_send_register (gchar* accountID, gboolean enable);
/**
* ConfigurationManager - Add an account to the list

View File

@ -690,7 +690,7 @@ void SFLPhoneView::transfer()
{
Call* call = callTreeModel->getCurrentItem();
if(!call) {
kDebug() << "Error : Transfering when no item selected. Should not happen.";
kDebug() << "Error : Transferring when no item selected. Should not happen.";
}
else {
action(call, CALL_ACTION_TRANSFER);

View File

@ -190,7 +190,7 @@
<tp:docstring>
Send account registration (REGISTER) to the registrar.
</tp:docstring>
the account if expire=1, unregister if expire=0.
Register the account if enable=true, unregister if enable=false.
@param[in] input accountID
-->
@ -199,10 +199,10 @@
The account ID
</tp:docstring>
</arg>
<arg type="i" name="expire" direction="in">
<arg type="b" name="enable" direction="in">
<tp:docstring>
<p>To register, expire must be 1.</p>
<p>To un-register, expire must be 0.</p>
<p>To register, enable must be true.</p>
<p>To un-register, enable must be false.</p>
</tp:docstring>
</arg>
</method>

View File

@ -560,7 +560,7 @@ void Call::refuse()
void Call::acceptTransf()
{
CallManagerInterface & callManager = CallManagerInterfaceSingleton::getInstance();
qDebug() << "Accepting call and transfering it to number : " << m_TransferNumber << ". callId : " << m_CallId;
qDebug() << "Accepting call and transferring it to number : " << m_TransferNumber << ". callId : " << m_CallId;
callManager.accept(m_CallId);
callManager.transfer(m_CallId, m_TransferNumber);
// m_HistoryState = TRANSFERED;
@ -634,7 +634,7 @@ void Call::call()
void Call::transfer()
{
CallManagerInterface & callManager = CallManagerInterfaceSingleton::getInstance();
qDebug() << "Transfering call to number : " << m_TransferNumber << ". callId : " << m_CallId;
qDebug() << "Transferring call to number : " << m_TransferNumber << ". callId : " << m_CallId;
callManager.transfer(m_CallId, m_TransferNumber);
this->m_pStopTime = new QDateTime(QDateTime::currentDateTime());
}