Commit cb5eaebb authored by Emmanuel Milou's avatar Emmanuel Milou

Restore IAXVoIPLink, restore Mutex

parent 0f45206f
......@@ -123,7 +123,8 @@ class Account{
void setRegistrationState( RegistrationState state );
//TODO inline?
/* inline functions */
/* They should be treated like macro definitions by the C++ compiler */
inline std::string getUsername( void ) { return _username; }
inline void setUsername( std::string username) { _username = username; }
......
/*
* Copyright (C) 2008 Savoir-Faire Linux inc.
* Copyright (C) 2008 2009 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
......@@ -19,14 +19,6 @@
#include "alsalayer.h"
void* ringtoneThreadEntry( void *ptr);
static pthread_t ringtone_thread;
bool ringtone_thread_is_running;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
// Constructor
AlsaLayer::AlsaLayer( ManagerImpl* manager )
: AudioLayer( manager , ALSA )
......@@ -40,21 +32,12 @@ pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
, IDSoundCards()
{
_debug(" Constructor of AlsaLayer called\n");
// The flag to stop the ringtone thread loop
ringtone_thread_is_running = false;
}
// Destructor
AlsaLayer::~AlsaLayer (void)
{
_debugAlsa("Close ALSA streams\n");
closeCaptureStream();
closePlaybackStream();
deviceClosed = true;
ringtone_thread_is_running = false;
//pthread_join(ringtone_thread, NULL);
closeLayer();
}
void
......@@ -64,8 +47,6 @@ AlsaLayer::closeLayer()
closeCaptureStream();
closePlaybackStream();
deviceClosed = true;
ringtone_thread_is_running = false;
}
bool
......@@ -156,27 +137,6 @@ AlsaLayer::stopStream(void)
}
void* ringtoneThreadEntry( void *ptr )
{
while( ringtone_thread_is_running )
{
( ( AlsaLayer *) ptr) -> playTones();
//sleep(0.1);
}
/*
pthread_mutex_lock(&mut);
while( ((AlsaLayer*)ptr)->_manager->getTelephoneTone() == NULL )
{
pthread_cond_wait(&cond, &mut);
}
( AlsaLayer *) ptr -> playTones();
pthread_mutex_unlock(&mut);*/
return 0;
}
void
AlsaLayer::fillHWBuffer( void)
{
......@@ -242,13 +202,6 @@ AlsaLayer::putUrgent(void* buffer, int toCopy)
return nbBytes;
}
void AlsaLayer::trigger_thread(void)
{
_debug("Wake up the ringtone thread\n");
pthread_cond_broadcast(&cond);
}
int
AlsaLayer::canGetMic()
{
......@@ -299,13 +252,6 @@ AlsaLayer::playTones( void )
int frames;
int maxBytes;
//pthread_mutex_lock(&mut);
//while(!_manager-> getTelephoneTone() && !_manager->getTelephoneFile())
//{
_debug("Make the ringtone thread wait\n");
pthread_cond_wait(&cond, &mut);
//}
//frames = _periodSize ;
frames = 940 ;
maxBytes = frames * sizeof(SFLDataFormat) ;
......@@ -324,7 +270,6 @@ AlsaLayer::playTones( void )
}
// free the temporary data buffer
free( out ); out = 0;
//pthread_mutex_unlock(&mut);
}
......@@ -445,18 +390,7 @@ bool AlsaLayer::alsa_set_params( snd_pcm_t *pcm_handle, int type, int rate ){
}
if( type == 1 ){
/*if( (err = snd_async_add_pcm_handler( &_AsyncHandler, pcm_handle , AlsaCallBack, this ) < 0)){
_debugAlsa(" Unable to install the async callback handler (%s)\n", snd_strerror(err));
return false;
}*/
// So the loop could start when the ringtone thread entry function is reached
ringtone_thread_is_running = true;
/*if( pthread_create(&ringtone_thread, NULL, ringtoneThreadEntry, this) != 0 )
{
_debug("Unable to start the ringtone posix thread\n");
return false;
}*/
}
snd_pcm_sw_params_free( swparams );
......
......@@ -21,8 +21,7 @@
#define _ALSA_LAYER_H
#include "audiolayer.h"
#include <pthread.h>
#include <alsa/asoundlib.h>
class RingBuffer;
class ManagerImpl;
......@@ -48,8 +47,6 @@ class AlsaLayer : public AudioLayer {
*/
~AlsaLayer(void);
void trigger_thread(void);
void closeLayer( void );
/**
......
......@@ -22,21 +22,15 @@
#ifndef _AUDIO_LAYER_H
#define _AUDIO_LAYER_H
#include "../global.h"
#include "../manager.h"
#include "global.h"
#include "audiodevice.h"
#include "ringbuffer.h"
#include "manager.h"
#include <cc++/thread.h> // for ost::Mutex
#include <vector>
#include <alsa/asoundlib.h>
#include <pulse/pulseaudio.h>
#include <iostream>
#include <istream>
#include <sstream>
#define FRAME_PER_BUFFER 160
......@@ -86,8 +80,6 @@ class AudioLayer {
virtual void closeLayer( void ) = 0;
virtual void trigger_thread(void)=0;
/**
* Check if no devices are opened, otherwise close them.
* Then open the specified devices by calling the private functions open_device
......
......@@ -52,14 +52,16 @@ AudioRtp::~AudioRtp (void) {
int
AudioRtp::createNewSession (SIPCall *ca) {
//ost::MutexLock m(_threadMutex);
// something should stop the thread before...
if ( _RTXThread != 0 ) {
_debug("! ARTP Failure: Thread already exists..., stopping it\n");
delete _RTXThread; _RTXThread = 0;
//return -1;
}
ost::MutexLock m(_threadMutex);
// something should stop the thread before...
if ( _RTXThread != 0 ) {
_debug("**********************************************************\n");
_debug("! ARTP Failure: Thread already exists..., stopping it\n");
_debug("**********************************************************\n");
delete _RTXThread; _RTXThread = 0;
//return -1;
}
// Start RTP Send/Receive threads
_symmetric = Manager::instance().getConfigInt(SIGNALISATION,SYMMETRIC) ? true : false;
......@@ -79,7 +81,7 @@ AudioRtp::createNewSession (SIPCall *ca) {
void
AudioRtp::closeRtpSession () {
//ost::MutexLock m(_threadMutex);
ost::MutexLock m(_threadMutex);
// This will make RTP threads finish.
// _debug("Stopping AudioRTP\n");
try {
......@@ -88,8 +90,8 @@ AudioRtp::closeRtpSession () {
_debugException("! ARTP Exception: when stopping audiortp\n");
throw;
}
AudioLayer* audiolayer = Manager::instance().getAudioDriver();
audiolayer->stopStream();
//AudioLayer* audiolayer = Manager::instance().getAudioDriver();
//audiolayer->stopStream();
}
////////////////////////////////////////////////////////////////////////////////
......@@ -99,7 +101,7 @@ AudioRtpRTX::AudioRtpRTX (SIPCall *sipcall, bool sym) : time(new ost::Time()), _
_sym(sym), micData(NULL), micDataConverted(NULL), micDataEncoded(NULL), spkrDataDecoded(NULL), spkrDataConverted(NULL),
converter(NULL), _layerSampleRate(),_codecSampleRate(), _layerFrameSize(), _audiocodec(NULL)
{
setCancel(cancelDeferred);
setCancel(cancelDefault);
// AudioRtpRTX should be close if we change sample rate
// TODO: Change bind address according to user settings.
// TODO: this should be the local ip not the external (router) IP
......
......@@ -29,6 +29,8 @@
#include <string>
#include <stdlib.h>
#include <sstream>
#include <map>
#include <vector>
#define SFLPHONED_VERSION "0.9.2-4" /** Version number */
......
......@@ -22,8 +22,8 @@
#include "iaxaccount.h"
#include "iaxvoiplink.h"
IAXAccount::IAXAccount(const AccountID& accountID)
: Account(accountID, "iax2")
IAXAccount::IAXAccount(const AccountID& accountID)
: Account(accountID, "iax2")
{
_link = new IAXVoIPLink(accountID);
}
......@@ -37,17 +37,12 @@ IAXAccount::~IAXAccount()
int IAXAccount::registerVoIPLink()
{
IAXVoIPLink *thislink;
_link->init();
thislink = dynamic_cast<IAXVoIPLink*> (_link);
if (thislink) {
// Stuff needed for IAX registration
thislink->setHost(Manager::instance().getConfigString(_accountID, HOSTNAME));
thislink->setUser(Manager::instance().getConfigString(_accountID, USERNAME));
thislink->setPass(Manager::instance().getConfigString(_accountID, PASSWORD));
}
// Stuff needed for IAX registration
setHostname(Manager::instance().getConfigString(_accountID, HOSTNAME));
setUsername(Manager::instance().getConfigString(_accountID, USERNAME));
setPassword(Manager::instance().getConfigString(_accountID, PASSWORD));
_link->sendRegister( _accountID );
......
This diff is collapsed.
......@@ -166,21 +166,7 @@ class IAXVoIPLink : public VoIPLink
bool isContactPresenceSupported() { return false; }
public: // iaxvoiplink only
/**
* @param host Set the host name
*/
void setHost(const std::string& host) { _host = host; }
/**
* @param user Set the user name
*/
void setUser(const std::string& user) { _user = user; }
/**
* @param pass Set the password
*/
void setPass(const std::string& pass) { _pass = pass; }
void updateAudiolayer( void );
void setStunServer( const std::string &server ) {};
......@@ -194,7 +180,7 @@ class IAXVoIPLink : public VoIPLink
* @param msgcount The value sent by IAX in the REGACK message
* @return int The number of new messages waiting for the current registered user
*/
int processIAXMsgCount( int msgcount );
int processIAXMsgCount( int msgcount );
/**
......@@ -253,28 +239,12 @@ class IAXVoIPLink : public VoIPLink
*/
bool iaxOutgoingInvite(IAXCall* call);
/**
* Convert CodecMap to IAX format using IAX constants
* @return `format` ready to go into iax_* calls
*/
int iaxCodecMapToFormat(IAXCall* call);
/** Threading object */
EventThread* _evThread;
/** registration session : 0 if not register */
struct iax_session* _regSession;
/** IAX Host */
std::string _host;
/** IAX User */
std::string _user;
/** IAX Password */
std::string _pass;
/** 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. */
......
......@@ -57,20 +57,20 @@ ManagerImpl::ManagerImpl (void)
: _hasTriedToRegister(false)
, _config()
, _currentCallId2()
//, _currentCallMutex()
, _currentCallMutex()
, _codecBuilder(NULL)
, _audiodriver(NULL)
, _dtmfKey(NULL)
, _codecDescriptorMap()
//, _toneMutex()
, _toneMutex()
, _telephoneTone(NULL)
, _audiofile()
, _spkr_volume(0)
, _mic_volume(0)
//, _mutex()
, _mutex()
, _dbus(NULL)
, _waitingCall()
//, _waitingCallMutex()
, _waitingCallMutex()
, _nbIncomingWaitingCall(0)
, _path("")
, _exist(0)
......@@ -79,7 +79,7 @@ ManagerImpl::ManagerImpl (void)
, _firewallAddr("")
, _hasZeroconf(false)
, _callAccountMap()
//, _callAccountMapMutex()
, _callAccountMapMutex()
, _accountMap()
{
......@@ -158,13 +158,11 @@ void ManagerImpl::terminate()
bool
ManagerImpl::isCurrentCall(const CallID& callId) {
//ost::MutexLock m(_currentCallMutex);
return (_currentCallId2 == callId ? true : false);
}
bool
ManagerImpl::hasCurrentCall() {
//ost::MutexLock m(_currentCallMutex);
_debug("Current call ID = %s\n", _currentCallId2.c_str());
if ( _currentCallId2 != "") {
return true;
......@@ -174,13 +172,12 @@ ManagerImpl::hasCurrentCall() {
const CallID&
ManagerImpl::getCurrentCallId() {
//ost::MutexLock m(_currentCallMutex);
return _currentCallId2;
}
void
ManagerImpl::switchCall(const CallID& id ) {
//ost::MutexLock m(_currentCallMutex);
ost::MutexLock m(_currentCallMutex);
_currentCallId2 = id;
}
......@@ -403,7 +400,6 @@ ManagerImpl::saveConfig (void)
ManagerImpl::initRegisterAccounts()
{
int status;
//TODO What the flag is for ??
bool flag = true;
AccountMap::iterator iter;
......@@ -527,20 +523,19 @@ ManagerImpl::playDtmf(char code, bool isTalking)
// Multi-thread
bool
ManagerImpl::incomingCallWaiting() {
//ost::MutexLock m(_waitingCallMutex);
return (_nbIncomingWaitingCall > 0) ? true : false;
}
void
ManagerImpl::addWaitingCall(const CallID& id) {
//ost::MutexLock m(_waitingCallMutex);
ost::MutexLock m(_waitingCallMutex);
_waitingCall.insert(id);
_nbIncomingWaitingCall++;
}
void
ManagerImpl::removeWaitingCall(const CallID& id) {
//ost::MutexLock m(_waitingCallMutex);
ost::MutexLock m(_waitingCallMutex);
// should return more than 1 if it erase a call
if (_waitingCall.erase(id)) {
_nbIncomingWaitingCall--;
......@@ -549,7 +544,6 @@ ManagerImpl::removeWaitingCall(const CallID& id) {
bool
ManagerImpl::isWaitingCall(const CallID& id) {
//ost::MutexLock m(_waitingCallMutex);
CallIDSet::iterator iter = _waitingCall.find(id);
if (iter != _waitingCall.end()) {
return false;
......@@ -701,9 +695,9 @@ ManagerImpl::playATone(Tone::TONEID toneId) {
if (!hasToPlayTone) return false;
if (_telephoneTone != 0) {
//_toneMutex.enterMutex();
_toneMutex.enterMutex();
_telephoneTone->setCurrentTone(toneId);
//_toneMutex.leaveMutex();
_toneMutex.leaveMutex();
AudioLoop* audioloop = getTelephoneTone();
unsigned int nbSampling = audioloop->getSize();
......@@ -740,16 +734,16 @@ ManagerImpl::stopTone(bool stopAudio=true) {
}
//_toneMutex.enterMutex();
_toneMutex.enterMutex();
if (_telephoneTone != 0) {
_telephoneTone->setCurrentTone(Tone::TONE_NULL);
}
//_toneMutex.leaveMutex();
_toneMutex.leaveMutex();
// for ringing tone..
//_toneMutex.enterMutex();
_toneMutex.enterMutex();
_audiofile.stop();
//_toneMutex.leaveMutex();
_toneMutex.leaveMutex();
}
/**
......@@ -786,7 +780,6 @@ ManagerImpl::congestion () {
void
ManagerImpl::ringback () {
playATone(Tone::TONE_RINGTONE);
getAudioDriver()->trigger_thread();
}
/**
......@@ -813,13 +806,13 @@ ManagerImpl::ringtone()
int sampleRate = audiolayer->getSampleRate();
AudioCodec* codecForTone = _codecDescriptorMap.getFirstCodecAvailable();
//_toneMutex.enterMutex();
_toneMutex.enterMutex();
bool loadFile = _audiofile.loadFile(ringchoice, codecForTone , sampleRate);
//_toneMutex.leaveMutex();
_toneMutex.leaveMutex();
if (loadFile) {
//_toneMutex.enterMutex();
_toneMutex.enterMutex();
_audiofile.start();
//_toneMutex.leaveMutex();
_toneMutex.leaveMutex();
if(CHECK_INTERFACE( layer, ALSA )){
/*int size = _audiofile.getSize();
SFLDataFormat output[ size ];
......@@ -846,7 +839,7 @@ ManagerImpl::ringtone()
ManagerImpl::getTelephoneTone()
{
if(_telephoneTone != 0) {
//ost::MutexLock m(_toneMutex);
ost::MutexLock m(_toneMutex);
return _telephoneTone->getCurrentTone();
}
else {
......@@ -857,7 +850,7 @@ ManagerImpl::getTelephoneTone()
AudioLoop*
ManagerImpl::getTelephoneFile()
{
//ost::MutexLock m(_toneMutex);
ost::MutexLock m(_toneMutex);
if(_audiofile.isStarted()) {
return &_audiofile;
} else {
......@@ -1735,7 +1728,7 @@ int ManagerImpl::getSipPort( void )
ManagerImpl::getCallStatus(const std::string& sequenceId UNUSED)
{
if (!_dbus) { return false; }
//ost::MutexLock m(_callAccountMapMutex);
ost::MutexLock m(_callAccountMapMutex);
CallAccountMap::iterator iter = _callAccountMap.begin();
TokenList tk;
std::string code;
......@@ -2032,7 +2025,7 @@ ManagerImpl::associateCallToAccount(const CallID& callID, const AccountID& accou
{
if (getAccountFromCall(callID) == AccountNULL) { // nothing with the same ID
if ( accountExists(accountID) ) { // account id exist in AccountMap
//ost::MutexLock m(_callAccountMapMutex);
ost::MutexLock m(_callAccountMapMutex);
_callAccountMap[callID] = accountID;
_debug("Associate Call %s with Account %s\n", callID.data(), accountID.data());
return true;
......@@ -2047,7 +2040,7 @@ ManagerImpl::associateCallToAccount(const CallID& callID, const AccountID& accou
AccountID
ManagerImpl::getAccountFromCall(const CallID& callID)
{
//ost::MutexLock m(_callAccountMapMutex);
ost::MutexLock m(_callAccountMapMutex);
CallAccountMap::iterator iter = _callAccountMap.find(callID);
if ( iter == _callAccountMap.end()) {
return AccountNULL;
......@@ -2059,7 +2052,7 @@ ManagerImpl::getAccountFromCall(const CallID& callID)
bool
ManagerImpl::removeCallAccount(const CallID& callID)
{
//ost::MutexLock m(_callAccountMapMutex);
ost::MutexLock m(_callAccountMapMutex);
if ( _callAccountMap.erase(callID) ) {
return true;
}
......
......@@ -865,7 +865,7 @@ class ManagerImpl {
CallID _currentCallId2;
/** Protected current call access */
//ost::Mutex _currentCallMutex;
ost::Mutex _currentCallMutex;
/** Vector of CodecDescriptor */
CodecDescriptor* _codecBuilder;
......@@ -883,7 +883,7 @@ class ManagerImpl {
/////////////////////
// Protected by Mutex
/////////////////////
//ost::Mutex _toneMutex;
ost::Mutex _toneMutex;
TelephoneTone* _telephoneTone;
AudioFile _audiofile;
......@@ -896,7 +896,7 @@ class ManagerImpl {
// Multithread variable (protected by _mutex)
//
/** Mutex to protect access to code section */
//ost::Mutex _mutex;
ost::Mutex _mutex;
// Multithread variable (non protected)
DBusManagerImpl * _dbus;
......@@ -905,7 +905,7 @@ class ManagerImpl {
CallIDSet _waitingCall;
/** Protect waiting call list, access by many voip/audio threads */
//ost::Mutex _waitingCallMutex;
ost::Mutex _waitingCallMutex;
/** Number of waiting call, synchronize with waitingcall callidvector */
unsigned int _nbIncomingWaitingCall;
......@@ -953,7 +953,7 @@ class ManagerImpl {
CallAccountMap _callAccountMap;
/** Mutex to lock the call account map (main thread + voiplink thread) */
//ost::Mutex _callAccountMapMutex;
ost::Mutex _callAccountMapMutex;
/** Associate a new CallID to a AccountID
* Protected by mutex
......
......@@ -52,19 +52,13 @@ SIPAccount::~SIPAccount()
int SIPAccount::registerVoIPLink()
{
int status, useStun;
SIPVoIPLink *thislink;
int status;
/* Retrieve the account information */
/* Stuff needed for SIP registration */
setHostname(Manager::instance().getConfigString(_accountID,HOSTNAME));
setUsername(Manager::instance().getConfigString(_accountID, USERNAME));
setPassword(Manager::instance().getConfigString(_accountID, PASSWORD));
/* Retrieve STUN stuff */
/* STUN configuration is attached to a voiplink because it is applied to every accounts (PJSIP limitation)*/
thislink = dynamic_cast<SIPVoIPLink*> (_link);
if (thislink) {
}
/* Start registration */
status = _link->sendRegister( _accountID );
......
......@@ -77,22 +77,10 @@ class SIPAccount : public Account
bool fullMatch(const std::string& username, const std::string& hostname);
bool userMatch(const std::string& username);
inline std::string getHostname( void ) { return _hostname; }
inline void setHostname( std::string hostname) { _hostname = hostname; }
inline std::string getPassword( void ) { return _password; }
inline void setPassword( std::string password ) { _password = password; }
inline std::string getAlias( void ) { return _alias; }
inline void setAlias( std::string alias ) { _alias = alias; }
inline std::string getType( void ) { return _type; }
inline void setType( std::string type ) { _type = type; }
pjsip_regc* getRegistrationInfo( void ) { return _regc; }
void setRegistrationInfo( pjsip_regc *regc ) { _regc = regc; }
//TODO See if it useful
/* Registration flag */
bool isRegister() {return _bRegister;}
void setRegister(bool result) {_bRegister = result;}
......
......@@ -211,13 +211,13 @@ SIPVoIPLink::terminate()
SIPVoIPLink::terminateSIPCall()
{
//ost::MutexLock m(_callMapMutex);
ost::MutexLock m(_callMapMutex);
CallMap::iterator iter = _callMap.begin();
SIPCall *call;
while( iter != _callMap.end() ) {
call = dynamic_cast<SIPCall*>(iter->second);
if (call) {
//TODO terminate the sip call
// terminate the sip call
delete call; call = 0;
}
iter++;
......@@ -517,17 +517,17 @@ SIPVoIPLink::onhold(const CallID& id)
if (call==0) { _debug("! SIP Error: call doesn't exist\n"); return false; }
_mutexSIP.enterMutex();
// Stop sound
call->setAudioStart(false);
call->setState(Call::Hold);
_debug("* SIP Info: Stopping AudioRTP for onhold action\n");
_audiortp->closeRtpSession();
//_mutexSIP.enterMutex();
_audiortp->closeRtpSession();
//_mutexSIP.leaveMutex();
local_sdp = call->getLocalSDPSession();
_mutexSIP.leaveMutex();
if( local_sdp == NULL ){
_debug("! SIP Failure: unable to find local_sdp\n");
return false;
......@@ -1145,7 +1145,6 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
PJ_ASSERT_RETURN( status == PJ_SUCCESS, 1 );
// Init the callback for INVITE session:
// TODO The invite session as global ?
pj_bzero(&inv_cb, sizeof (inv_cb));
inv_cb.on_state_changed = &call_on_state_changed;
......@@ -1171,7 +1170,7 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
_debug("UserAgent: pjsip version %s for %s initialized\n", pj_get_version(), PJ_OS_NAME);
//TODO Create the secondary thread to poll sip events
// Create the secondary thread to poll sip events
_evThread->start();
/* Done! */
......@@ -1435,9 +1434,6 @@ std::string SIPVoIPLink::getSipTo(const std::string& to_url, std::string hostnam
SIPVoIPLink *link;
pjsip_msg *msg;
_debug("UserAgent: TSX Changed! The tsx->state is %d; tsx->role is %d; code is %d; method id is %.*s.\n",
tsx->state, tsx->role, tsx->status_code, (int)tsx->method.name.slen, tsx->method.name.ptr);
if(pj_strcmp2(&tsx->method.name, "INFO") == 0) {
// Receive a INFO message, ingore it!
return;
......
......@@ -42,7 +42,7 @@ class AudioRtp;
#define RANDOM_SIP_PORT rand() % 64000 + 1024
// To set the verbosity. From 0 (min) to 6 (max)
#define PJ_LOG_LEVEL 5
#define PJ_LOG_LEVEL 1
/**
* @file sipvoiplink.h
......
/*
* Copyright (C) 2004-2005 Savoir-Faire Linux inc.
* Author: Yun Liu <yun.liu@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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _SIPMANAGER_H
#define _SIPMANAGER_H
#include <pjsip.h>
#include <pjlib-util.h>
#include <pjlib.h>
#include <pjnath/stun_config.h>
//TODO Remove this include if we don't need anything from it
#include <pjsip_simple.h>
#include <pjsip_ua.h>
#include <pjmedia/sdp.h>
#include <pjmedia/sdp_neg.h>