Commit 36e857fc authored by Guillaume Roguez's avatar Guillaume Roguez Committed by gerrit2

removing IAX account and libiax dependency

This patch removes all IAX account code and libiax dependency in contrib.
References in documentation have also been removed where needed.

Change-Id: Ifff23725ccf7e1a6820dbc6f57256138a0fca042
Tuleap: #813
parent 7479d74c
......@@ -22,7 +22,7 @@ Introduction
Ring is a Voice-over-IP software phone. We want it to be:
- user friendly (fast, sleek, easy to learn interface)
- professional grade (transfers, holds, optimal audio quality)
- fully compatible with Asterisk (SIP and IAX protocols)
- compatible with Asterisk (using SIP account)
- de-centralized call (P2P-DHT)
- customizable
......
......@@ -31,7 +31,7 @@
<ul>
<li>CONFIG_ACCOUNT_ENABLE: True or False (Default: True)</li>
<li>CONFIG_ACCOUNT_RESOLVE_ONCE</li>
<li>CONFIG_ACCOUNT_TYPE: SIP or IAX2 (Default: SIP)</li>
<li>CONFIG_ACCOUNT_TYPE: SIP or RING</li>
<li>HOSTNAME: The IP adress or hostname of the registrar</li>
<li>USERNAME: The username (or extension) of the account</li>
<li>PASSWORD: The password associated to the account</li>
......@@ -621,11 +621,6 @@
<!-- General Settings Panel -->
<method name="isIax2Enabled" tp:name-for-bindings="isIax2Enabled">
<arg type="i" name="res" direction="out">
</arg>
</method>
<method name="getHistoryLimit" tp:name-for-bindings="getHistoryLimit">
<arg type="i" name="days" direction="out">
</arg>
......
......@@ -325,12 +325,6 @@ DBusConfigurationManager::getSupportedAudioManagers()
};
}
auto
DBusConfigurationManager::isIax2Enabled() -> decltype(DRing::isIax2Enabled())
{
return DRing::isIax2Enabled();
}
auto
DBusConfigurationManager::getRecordPath() -> decltype(DRing::getRecordPath())
{
......
......@@ -103,7 +103,6 @@ class DBusConfigurationManager :
std::string getAudioManager();
bool setAudioManager(const std::string& api);
std::vector<std::string> getSupportedAudioManagers();
int32_t isIax2Enabled();
std::string getRecordPath();
void setRecordPath(const std::string& recPath);
bool getIsAlwaysRecording();
......
......@@ -530,22 +530,6 @@ AS_CASE(["$with_opus"],
[PKG_CHECK_MODULES([opus], [opus], [HAVE_OPUS=1], [HAVE_OPUS=0])])
AM_CONDITIONAL([BUILD_OPUS], [test "$HAVE_OPUS" -eq 1])
AC_ARG_WITH([iax],
AS_HELP_STRING([--without-iax], [Ignore presence of iax and disable it]))
AS_IF([test "x$with_iax" != "xno"],
[AC_CHECK_HEADER("iax/iax-client.h", [have_iax=yes], [have_iax=no])],
[have_iax=no])
# only fail if IAX was explicitly requested but not found
AS_IF([test "x$have_iax" = "xyes"],
[AC_DEFINE([HAVE_IAX], 1, [Define if you have libiax])
AM_CONDITIONAL(USE_IAX, `true`)],
[AS_IF([test "x$with_iax" = "xyes"],
[AC_MSG_ERROR([iax requested but not found])])
AC_DEFINE([HAVE_IAX], 0, [Define if you have libiax])
AM_CONDITIONAL(USE_IAX, `false`)])
# dht is default-enabled, but requires gnutls
AC_ARG_ENABLE([dht],
AS_HELP_STRING([--disable-dht], [disable support for dht]))
......@@ -617,7 +601,6 @@ AC_CONFIG_FILES([Makefile \
src/Makefile \
src/sip/Makefile \
src/im/Makefile \
src/iax/Makefile \
src/ringdht/Makefile \
src/media/Makefile \
src/media/audio/Makefile \
......
#IAX
IAX_VERSION = 0e5980f1d78ce462e2d1ed6bc39ff35c8341f201
IAX_URL = https://gitlab.savoirfairelinux.com/sflphone/libiax2/repository/archive.tar.gz?ref=$(IAX_VERSION)
PKGS += iax
$(TARBALLS)/iax-git.tar.gz:
$(call download,$(IAX_URL))
.sum-iax: iax-git.tar.gz
$(warning $@ not implemented)
touch $@
iax: iax-git.tar.gz .sum-iax
$(UNPACK)
mv libiax2-$(IAX_VERSION)-$(IAX_VERSION) $@
touch $@
.iax: iax
$(RECONF)
cd $< && $(HOSTVARS) ./configure $(HOSTCONF)
cd $< && $(MAKE) install
touch $@
......@@ -28,14 +28,6 @@ INSTANT_MESSAGING_SUBDIR = im
IM_LIBA=./im/libim.la
endif
# Redefine the USE_IAX variable here, so that it could be used in manager
if USE_IAX
IAX_SUBDIR=iax
IAX_CXXFLAG=-DUSE_IAX
IAX_LIBA=./iax/libiaxlink.la
IAX_LIB=-liax
endif
if USE_DHT
RINGACC_SUBDIR=ringdht
RINGACC_CXXFLAG=-DUSE_DHT
......@@ -47,7 +39,7 @@ TLS_LIB = @GNUTLS_LIBS@
TLS_CFLAGS = @GNUTLS_CFLAGS@
endif
SUBDIRS = client media config hooks sip upnp security $(IAX_SUBDIR) $(RINGACC_SUBDIR) $(INSTANT_MESSAGING_SUBDIR) $(RING_VIDEO_SUBDIR)
SUBDIRS = client media config hooks sip upnp security $(RINGACC_SUBDIR) $(INSTANT_MESSAGING_SUBDIR) $(RING_VIDEO_SUBDIR)
# libring
......@@ -62,7 +54,6 @@ libring_la_LIBADD = \
./security/libsecurity.la \
./upnp/libupnpcontrol.la \
$(RINGACC_LIBA) \
$(IAX_LIBA) \
$(IM_LIBA) \
$(RING_VIDEO_LIBS)
......@@ -78,7 +69,6 @@ libring_la_LDFLAGS = \
@LIBUPNP_LIBS@ \
@PORTAUDIO_LIBS@ \
$(TLS_LIB) \
$(IAX_LIB) \
$(IM_LIB) \
$(PCRE_LIBS)
......
......@@ -257,7 +257,7 @@ Account::unserialize(const YAML::Node& node)
void
Account::setAccountDetails(const std::map<std::string, std::string> &details)
{
// Account setting common to SIP and IAX
// Account setting common to any account type
parseString(details, Conf::CONFIG_ACCOUNT_ALIAS, alias_);
parseString(details, Conf::CONFIG_ACCOUNT_DISPLAYNAME, displayName_);
parseBool(details, Conf::CONFIG_ACCOUNT_ENABLE, enabled_);
......
......@@ -72,7 +72,7 @@ class VoipLinkException : public std::runtime_error
/**
* @file account.h
* @brief Interface to protocol account (SIPAccount, IAXAccount)
* @brief Interface to protocol account (ex: SIPAccount)
* It can be enable on loading or activate after.
* It contains account, configuration, VoIP Link and Calls (inside the VoIPLink)
*/
......
......@@ -25,9 +25,6 @@
#include "account_factory.h"
#include "sip/sipaccount.h"
#if HAVE_IAX
#include "iax/iaxaccount.h"
#endif
#if HAVE_DHT
#include "ringdht/ringaccount.h"
#endif
......@@ -43,11 +40,6 @@ AccountFactory::AccountFactory()
auto sipfunc = [](const std::string& id){ return std::make_shared<SIPAccount>(id, true); };
generators_.insert(std::make_pair(SIPAccount::ACCOUNT_TYPE, sipfunc));
RING_DBG("registered %s account", SIPAccount::ACCOUNT_TYPE);
#if HAVE_IAX
auto iaxfunc = [](const std::string& id){ return std::make_shared<IAXAccount>(id); };
generators_.insert(std::make_pair(IAXAccount::ACCOUNT_TYPE, iaxfunc));
RING_DBG("registered %s account", IAXAccount::ACCOUNT_TYPE);
#endif
#if HAVE_DHT
auto dhtfunc = [](const std::string& id){ return std::make_shared<RingAccount>(id, false); };
generators_.insert(std::make_pair(RingAccount::ACCOUNT_TYPE, dhtfunc));
......
......@@ -38,9 +38,6 @@
#include "ip_utils.h"
#include "sip/sipaccount.h"
#include "ringdht/ringaccount.h"
#if HAVE_IAX
#include "iax/iaxaccount.h"
#endif
#include "audio/audiolayer.h"
#include "system_codec_container.h"
#include "account_const.h"
......@@ -350,10 +347,6 @@ getAccountTemplate(const std::string& accountType)
return ring::RingAccount("dummy", false).getAccountDetails();
else if (accountType == Account::ProtocolNames::SIP)
return ring::SIPAccount("dummy", false).getAccountDetails();
#if HAVE_IAX
else if (accountType == Account::ProtocolNames::IAX)
return ring::IAXAccount("dummy").getAccountDetails();
#endif
return {};
}
......@@ -600,12 +593,6 @@ setAgcState(bool enabled)
ring::Manager::instance().setAGCState(enabled);
}
int32_t
isIax2Enabled()
{
return HAVE_IAX;
}
std::string
getRecordPath()
{
......
......@@ -33,7 +33,6 @@ namespace Account {
namespace ProtocolNames {
constexpr static const char SIP [] = "SIP";
constexpr static const char IAX [] = "IAX";
constexpr static const char IP2IP [] = "IP2IP";
constexpr static const char RING [] = "RING";
......
......@@ -94,7 +94,6 @@ void muteRingtone(bool mute);
std::string getAudioManager();
bool setAudioManager(const std::string& api);
int32_t isIax2Enabled();
std::string getRecordPath();
void setRecordPath(const std::string& recPath);
bool getIsAlwaysRecording();
......
include $(top_srcdir)/globals.mak
if USE_IAX
noinst_LTLIBRARIES = libiaxlink.la
libiaxlink_la_SOURCES = \
iaxaccount.cpp \
iaxcall.cpp \
iaxvoiplink.cpp
libiaxlink_la_CXXFLAGS = \
-DUSE_IAX
noinst_HEADERS = \
iaxaccount.h \
iaxcall.h \
iaxvoiplink.h
endif
/*
* Copyright (C) 2004-2016 Savoir-faire Linux Inc.
*
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
* Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "iaxaccount.h"
#include "account_schema.h"
#include "iaxvoiplink.h"
#include "iaxcall.h"
#include "logger.h"
#include "manager.h"
#include "call_factory.h"
#include "intrin.h"
#include "config/yamlparser.h"
#include <yaml-cpp/yaml.h>
namespace ring {
constexpr const char * const IAXAccount::ACCOUNT_TYPE;
IAXAccount::IAXAccount(const std::string& accountID)
: Account(accountID), link_(new IAXVoIPLink(*this))
{}
void IAXAccount::serialize(YAML::Emitter &out)
{
out << YAML::BeginMap;
Account::serialize(out);
out << YAML::Key << PASSWORD_KEY << YAML::Value << password_;
out << YAML::EndMap;
}
void IAXAccount::unserialize(const YAML::Node &node)
{
Account::unserialize(node);
yaml_utils::parseValue(node, PASSWORD_KEY, password_);
}
void IAXAccount::setAccountDetails(const std::map<std::string, std::string> &details)
{
// Account setting common to SIP and IAX
Account::setAccountDetails(details);
parseString(details, Conf::CONFIG_ACCOUNT_PASSWORD, password_);
}
std::map<std::string, std::string> IAXAccount::getAccountDetails() const
{
std::map<std::string, std::string> a = Account::getAccountDetails();
a[Conf::CONFIG_ACCOUNT_PASSWORD] = password_;
return a;
}
std::map<std::string, std::string> IAXAccount::getVolatileAccountDetails() const
{
std::map<std::string, std::string> a = Account::getVolatileAccountDetails();
return a;
}
void IAXAccount::doRegister()
{
try {
link_->init(rand_);
sendRegister();
} catch (const VoipLinkException &e) {
RING_ERR("IAXAccount: %s", e.what());
}
}
void
IAXAccount::doUnregister(std::function<void(bool)> cb)
{
try {
sendUnregister();
link_->terminate();
} catch (const VoipLinkException &e) {
RING_ERR("IAXAccount: %s", e.what());
}
if (cb)
cb(true);
}
void
IAXAccount::loadConfig()
{
// If IAX is not supported, do not register this account
#if !HAVE_IAX
enabled_ = false;
#endif
}
template <>
std::shared_ptr<IAXCall>
IAXAccount::newIncomingCall(const std::string& from UNUSED)
{
auto& manager = Manager::instance();
return manager.callFactory.newCall<IAXCall, IAXAccount>(*this, manager.getNewCallID(),
Call::CallType::INCOMING);
}
template <>
std::shared_ptr<IAXCall>
IAXAccount::newOutgoingCall(const std::string& toUrl)
{
auto& manager = Manager::instance();
auto call = manager.callFactory.newCall<IAXCall, IAXAccount>(*this, manager.getNewCallID(),
Call::CallType::OUTGOING);
call->setPeerNumber(toUrl);
call->initRecFilename(toUrl);
iaxOutgoingInvite(call.get());
call->setState(Call::CallState::ACTIVE, Call::ConnectionState::PROGRESSING);
return call;
}
std::shared_ptr<Call>
IAXAccount::newOutgoingCall(const std::string& toUrl)
{
return newOutgoingCall<IAXCall>(toUrl);
}
void
IAXAccount::iaxOutgoingInvite(IAXCall* call)
{
std::lock_guard<std::mutex> lock(IAXVoIPLink::mutexIAX);
call->session = iax_session_new();
std::string username(getUsername());
std::string strNum(username + ":" + getPassword() + "@" + getHostname() + "/" + call->getPeerNumber());
/** @todo Make preference dynamic, and configurable */
const auto accountID = getAccountID();
int audio_format_preferred = call->getFirstMatchingFormat(call->getSupportedFormat(accountID), accountID);
int audio_format_capability = call->getSupportedFormat(accountID);
iax_call(call->session, username.c_str(), username.c_str(), strNum.c_str(),
NULL, 0, audio_format_preferred, audio_format_capability);
}
void
IAXAccount::sendRegister()
{
if (not isEnabled()) {
RING_WARN("Account must be enabled to register, ignoring");
return;
}
if (getHostname().empty())
throw VoipLinkException("Account hostname is empty");
if (getUsername().empty())
throw VoipLinkException("Account username is empty");
{
std::lock_guard<std::mutex> lock(IAXVoIPLink::mutexIAX);
regSession_.reset(iax_session_new());
}
if (regSession_) {
{
std::lock_guard<std::mutex> lock(IAXVoIPLink::mutexIAX);
RING_DBG("register IAXAccount %s", getHostname().c_str());
iax_register(regSession_.get(), getHostname().data(),
getUsername().data(), getPassword().data(), 120);
}
nextRefreshStamp_ = time(NULL) + 10;
setRegistrationState(RegistrationState::TRYING);
}
}
void
IAXAccount::sendUnregister(std::function<void(bool)> cb)
{
RING_DBG("unregister IAXAccount %s", getHostname().c_str());
destroyRegSession();
nextRefreshStamp_ = 0;
setRegistrationState(RegistrationState::UNREGISTERED);
if (cb)
cb(true);
}
void
IAXAccount::destroyRegSession()
{
std::lock_guard<std::mutex> lock(IAXVoIPLink::mutexIAX);
regSession_.reset();
}
void
IAXAccount::checkRegister()
{
if (nextRefreshStamp_ and nextRefreshStamp_ < time(NULL))
sendRegister();
}
bool
IAXAccount::matchRegSession(const iax_session* session) const
{
return regSession_.get() == session;
}
} // namespace ring
/*
* Copyright (C) 2004-2016 Savoir-faire Linux Inc.
*
* Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef IAXACCOUNT_H
#define IAXACCOUNT_H
#include "account.h"
#include "iaxvoiplink.h"
#include "ring_types.h" // enable_if_base_of
namespace YAML {
class Emitter;
class Node;
}
namespace ring {
class IAXCall;
/**
* @file: iaxaccount.h
* @brief An IAX Account specify IAX specific functions and objects (IAXCall/IAXVoIPLink)
*/
class IAXAccount : public Account {
public:
constexpr static const char * const ACCOUNT_TYPE = "IAX";
IAXAccount(const std::string& accountID);
virtual void serialize(YAML::Emitter &out);
virtual void unserialize(const YAML::Node &node);
const char* getAccountType() const {
return ACCOUNT_TYPE;
}
std::map<std::string, std::string> getAccountDetails() const;
virtual std::map<std::string, std::string> getVolatileAccountDetails() const;
void setNextRefreshStamp(int value) {
nextRefreshStamp_ = value;
}
// Actually useless, since config loading is done in init()
void loadConfig();
// Register an account
void doRegister();
// Unregister an account
void doUnregister(std::function<void(bool)> cb = std::function<void(bool)>());
/**
* Send out registration
*/
void sendRegister();
/**
* Destroy registration session
* @todo Send an IAX_COMMAND_REGREL to force unregistration upstream.
* Urgency: low
*/
void sendUnregister(std::function<void(bool)> cb = std::function<void(bool)>());
std::string getPassword() const {
return password_;
}
bool matchRegSession(const iax_session* session) const;
void destroyRegSession();
void checkRegister();
/**
* Implementation of Account::newOutgoingCall()
* Note: keep declaration before newOutgoingCall template.
*/
std::shared_ptr<Call> newOutgoingCall(const std::string& toUrl);
/**
* Create outgoing IAXCall.
* @param[in] toUrl The address to call
* @return std::shared_ptr<T> A shared pointer on the created call.
* The type of this instance is given in template argument.
* This type can be any base class of IAXCall class (included).
*/
template <class T=IAXCall>
std::shared_ptr<enable_if_base_of<T, IAXCall> >
newOutgoingCall(const std::string& toUrl);
/**
* Create incoming IAXCall.
* @param[in] from The origin uri of the call
* @return std::shared_ptr<T> A shared pointer on the created call.
* The type of this instance is given in template argument.
* This type can be any base class of IAXCall class (included).
*/
template <class T=IAXCall>
std::shared_ptr<enable_if_base_of<T, IAXCall> >
newIncomingCall(const std::string& from);
/**
* Set whether or not to use UPnP
*/
void setUseUPnP(bool) {
/* do nothing for now as UPnP isn't implemented for IAX */
}
private:
void setAccountDetails(const std::map<std::string, std::string> &details);
/**
* Send an outgoing call invite to iax
* @param call An IAXCall pointer
*/
void iaxOutgoingInvite(IAXCall* call);
/** registration session : nullptr if not register */
struct RegSessionDeleter {
void operator()(iax_session* session) { iax_destroy(session); }
};
std::unique_ptr<iax_session, RegSessionDeleter> regSession_ = nullptr;
// Account login information: password
std::string password_{};
std::unique_ptr<IAXVoIPLink> link_;
/** Timestamp of when we should refresh the registration up with
* the registrar. Values can be: EPOCH timestamp, 0 if we want no registration, 1
* to force a registration. */
int nextRefreshStamp_ = 0;
};
} // namespace ring
#endif
/*
* Copyright (C) 2004-2016 Savoir-faire Linux Inc.
*
* Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
* Author: Yan Morin <yan.morin@savoirfairelinux.com>
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <cstring>
#include <sys/socket.h>
#include <iax/iax-client.h>
#include <iax/frame.h>
#include "intrin.h"
#include "iaxcall.h"
#include "logger.h"
#include "manager.h"
#include "iaxaccount.h"
#include "iaxvoiplink.h"
#include "audio/ringbufferpool.h"
#include "audio/ringbuffer.h"
#if HAVE_INSTANT_MESSAGING
#include "im/instant_messaging.h"
#endif
namespace ring {
const char* const IAXCall::LINK_TYPE = IAXAccount::ACCOUNT_TYPE;
static int
codecToASTFormat(int c)
{
switch (c) {
case PAYLOAD_CODEC_ULAW:
return AST_FORMAT_ULAW;
case PAYLOAD_CODEC_GSM:
return AST_FORMAT_GSM;
case PAYLOAD_CODEC_ALAW:
return AST_FORMAT_ALAW;
case PAYLOAD_CODEC_ILBC_20:
return AST_FORMAT_ILBC;
case PAYLOAD_CODEC_SPEEX_8000:
return AST_FORMAT_SPEEX;
default:
RING_ERR("Codec %d not supported!", c);
return 0;
}
}
IAXCall::IAXCall(IAXAccount& account, const std::string& id, Call::CallType type)
: Call(account, id, type),
format(0),
session(NULL)
{
ringbuffer_ = Manager::instance().getRingBufferPool().createRingBuffer(getCallId());
}
int
IAXCall::getSupportedFormat(const std::string &accountID) const
{
const auto account = Manager::instance().getAccount(accountID);
int format_mask = 0;
if (account) {
std::vector<unsigned> codecs{account->getActiveCodecs(MEDIA_AUDIO)};
for (const auto &i : codecs)
format_mask |= codecToASTFormat(i);
} else