- format source code (indentation 4 space
This commit is contained in:
parent
7c346fbe9b
commit
10ec751e43
|
|
@ -15,181 +15,181 @@
|
|||
|
||||
|
||||
AudioManager::AudioManager()
|
||||
:mTerminal(nullptr), mAudioMonitoring(nullptr)
|
||||
:mTerminal(nullptr), mAudioMonitoring(nullptr)
|
||||
{
|
||||
mPlayer.setDelegate(this);
|
||||
mPlayer.setDelegate(this);
|
||||
}
|
||||
|
||||
AudioManager::~AudioManager()
|
||||
{
|
||||
// stop();
|
||||
// stop();
|
||||
}
|
||||
|
||||
AudioManager& AudioManager::instance()
|
||||
{
|
||||
static std::shared_ptr<AudioManager> GAudioManager;
|
||||
|
||||
if (!GAudioManager)
|
||||
GAudioManager = std::make_shared<AudioManager>();
|
||||
|
||||
return *GAudioManager;
|
||||
static std::shared_ptr<AudioManager> GAudioManager;
|
||||
|
||||
if (!GAudioManager)
|
||||
GAudioManager = std::make_shared<AudioManager>();
|
||||
|
||||
return *GAudioManager;
|
||||
}
|
||||
|
||||
void AudioManager::setTerminal(MT::Terminal* terminal)
|
||||
{
|
||||
mTerminal = terminal;
|
||||
mTerminal = terminal;
|
||||
}
|
||||
|
||||
MT::Terminal* AudioManager::terminal()
|
||||
{
|
||||
return mTerminal;
|
||||
return mTerminal;
|
||||
}
|
||||
|
||||
void AudioManager::setAudioMonitoring(Audio::DataConnection* monitoring)
|
||||
{
|
||||
mAudioMonitoring = monitoring;
|
||||
mAudioMonitoring = monitoring;
|
||||
}
|
||||
|
||||
Audio::DataConnection* AudioManager::audioMonitoring()
|
||||
{
|
||||
return mAudioMonitoring;
|
||||
return mAudioMonitoring;
|
||||
}
|
||||
|
||||
#define LOCK_MANAGER std::unique_lock<std::mutex> l(mGuard)
|
||||
void AudioManager::start(int usageId)
|
||||
{
|
||||
assert(mTerminal);
|
||||
LOCK_MANAGER;
|
||||
|
||||
ICELogInfo(<< "Start main audio with usage id " << usageId);
|
||||
assert(mTerminal);
|
||||
LOCK_MANAGER;
|
||||
|
||||
if (mUsage.obtain(usageId) > 1)
|
||||
return;
|
||||
ICELogInfo(<< "Start main audio with usage id " << usageId);
|
||||
|
||||
if (Audio::OsEngine::instance())
|
||||
Audio::OsEngine::instance()->open();
|
||||
if (mUsage.obtain(usageId) > 1)
|
||||
return;
|
||||
|
||||
if (!mAudioInput || !mAudioOutput)
|
||||
{
|
||||
// Disable AEC for now - because PVQA conflicts with speex AEC.
|
||||
std::shared_ptr<Audio::Enumerator> enumerator(Audio::Enumerator::make(usageId == atNull));
|
||||
if (!mTerminal->audio())
|
||||
{
|
||||
auto audio = std::make_shared<Audio::DevicePair>();
|
||||
audio->setAgc(true);
|
||||
audio->setAec(false);
|
||||
audio->setMonitoring(mAudioMonitoring);
|
||||
if (Audio::OsEngine::instance())
|
||||
Audio::OsEngine::instance()->open();
|
||||
|
||||
mTerminal->setAudio(audio);
|
||||
}
|
||||
if (!mAudioInput || !mAudioOutput)
|
||||
{
|
||||
// Disable AEC for now - because PVQA conflicts with speex AEC.
|
||||
std::shared_ptr<Audio::Enumerator> enumerator(Audio::Enumerator::make(usageId == atNull));
|
||||
if (!mTerminal->audio())
|
||||
{
|
||||
auto audio = std::make_shared<Audio::DevicePair>();
|
||||
audio->setAgc(true);
|
||||
audio->setAec(false);
|
||||
audio->setMonitoring(mAudioMonitoring);
|
||||
|
||||
if (!mAudioInput)
|
||||
{
|
||||
enumerator->open(Audio::myMicrophone);
|
||||
int inputIndex = enumerator->indexOfDefaultDevice();
|
||||
mTerminal->setAudio(audio);
|
||||
}
|
||||
|
||||
// Construct and set to terminal's audio pair input device
|
||||
if (usageId != atNull)
|
||||
mAudioInput = Audio::PInputDevice(Audio::InputDevice::make(enumerator->idAt(inputIndex)));
|
||||
else
|
||||
mAudioInput = Audio::PInputDevice(new Audio::NullInputDevice());
|
||||
if (!mAudioInput)
|
||||
{
|
||||
enumerator->open(Audio::myMicrophone);
|
||||
int inputIndex = enumerator->indexOfDefaultDevice();
|
||||
|
||||
mTerminal->audio()->setInput(mAudioInput);
|
||||
}
|
||||
// Construct and set to terminal's audio pair input device
|
||||
if (usageId != atNull)
|
||||
mAudioInput = Audio::PInputDevice(Audio::InputDevice::make(enumerator->idAt(inputIndex)));
|
||||
else
|
||||
mAudioInput = Audio::PInputDevice(new Audio::NullInputDevice());
|
||||
|
||||
if (!mAudioOutput)
|
||||
{
|
||||
Audio::Enumerator *enumerator = Audio::Enumerator::make(usageId == atNull);
|
||||
enumerator->open(Audio::mySpeaker);
|
||||
int outputIndex = enumerator->indexOfDefaultDevice();
|
||||
mTerminal->audio()->setInput(mAudioInput);
|
||||
}
|
||||
|
||||
// Construct and set terminal's audio pair output device
|
||||
if (usageId != atNull)
|
||||
{
|
||||
if (outputIndex >= enumerator->count())
|
||||
outputIndex = 0;
|
||||
if (!mAudioOutput)
|
||||
{
|
||||
Audio::Enumerator *enumerator = Audio::Enumerator::make(usageId == atNull);
|
||||
enumerator->open(Audio::mySpeaker);
|
||||
int outputIndex = enumerator->indexOfDefaultDevice();
|
||||
|
||||
mAudioOutput = Audio::POutputDevice(
|
||||
Audio::OutputDevice::make(enumerator->idAt(outputIndex)));
|
||||
}
|
||||
else
|
||||
mAudioOutput = Audio::POutputDevice(new Audio::NullOutputDevice());
|
||||
// Construct and set terminal's audio pair output device
|
||||
if (usageId != atNull)
|
||||
{
|
||||
if (outputIndex >= enumerator->count())
|
||||
outputIndex = 0;
|
||||
|
||||
mTerminal->audio()->setOutput(mAudioOutput);
|
||||
}
|
||||
}
|
||||
mAudioOutput = Audio::POutputDevice(
|
||||
Audio::OutputDevice::make(enumerator->idAt(outputIndex)));
|
||||
}
|
||||
else
|
||||
mAudioOutput = Audio::POutputDevice(new Audio::NullOutputDevice());
|
||||
|
||||
// Open audio
|
||||
if (mAudioInput)
|
||||
mAudioInput->open();
|
||||
if (mAudioOutput)
|
||||
mAudioOutput->open();
|
||||
mTerminal->audio()->setOutput(mAudioOutput);
|
||||
}
|
||||
}
|
||||
|
||||
// Open audio
|
||||
if (mAudioInput)
|
||||
mAudioInput->open();
|
||||
if (mAudioOutput)
|
||||
mAudioOutput->open();
|
||||
}
|
||||
|
||||
void AudioManager::close()
|
||||
{
|
||||
mUsage.clear();
|
||||
if (mAudioInput)
|
||||
{
|
||||
mAudioInput->close();
|
||||
mAudioInput.reset();
|
||||
}
|
||||
mUsage.clear();
|
||||
if (mAudioInput)
|
||||
{
|
||||
mAudioInput->close();
|
||||
mAudioInput.reset();
|
||||
}
|
||||
|
||||
if (mAudioOutput)
|
||||
{
|
||||
mAudioOutput->close();
|
||||
mAudioOutput.reset();
|
||||
}
|
||||
mPlayer.setOutput(Audio::POutputDevice());
|
||||
if (mAudioOutput)
|
||||
{
|
||||
mAudioOutput->close();
|
||||
mAudioOutput.reset();
|
||||
}
|
||||
mPlayer.setOutput(Audio::POutputDevice());
|
||||
}
|
||||
|
||||
void AudioManager::stop(int usageId)
|
||||
{
|
||||
LOCK_MANAGER;
|
||||
|
||||
ICELogInfo( << "Stop main audio with usage id " << usageId);
|
||||
if (mTerminal)
|
||||
{
|
||||
if (mTerminal->audio())
|
||||
mTerminal->audio()->player().release(usageId);
|
||||
}
|
||||
LOCK_MANAGER;
|
||||
|
||||
if (!mUsage.release(usageId))
|
||||
{
|
||||
close();
|
||||
ICELogInfo( << "Stop main audio with usage id " << usageId);
|
||||
if (mTerminal)
|
||||
{
|
||||
if (mTerminal->audio())
|
||||
mTerminal->audio()->player().release(usageId);
|
||||
}
|
||||
|
||||
// Reset device pair on terminal side
|
||||
mTerminal->setAudio(Audio::PDevicePair());
|
||||
if (!mUsage.release(usageId))
|
||||
{
|
||||
close();
|
||||
|
||||
if (Audio::OsEngine::instance())
|
||||
Audio::OsEngine::instance()->close();
|
||||
}
|
||||
// Reset device pair on terminal side
|
||||
mTerminal->setAudio(Audio::PDevicePair());
|
||||
|
||||
if (Audio::OsEngine::instance())
|
||||
Audio::OsEngine::instance()->close();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioManager::startPlayFile(int usageId, const std::string& path, AudioTarget target, LoopMode lm, int timelimit)
|
||||
{
|
||||
// Check if file exists
|
||||
Audio::PWavFileReader r = std::make_shared<Audio::WavFileReader>();
|
||||
// Check if file exists
|
||||
Audio::PWavFileReader r = std::make_shared<Audio::WavFileReader>();
|
||||
#ifdef TARGET_WIN
|
||||
r->open(StringHelper::makeTstring(path));
|
||||
r->open(StringHelper::makeTstring(path));
|
||||
#else
|
||||
r->open(path);
|
||||
r->open(path);
|
||||
#endif
|
||||
if (!r->isOpened())
|
||||
{
|
||||
ICELogError(<< "Cannot open file to play");
|
||||
return;
|
||||
}
|
||||
if (!r->isOpened())
|
||||
{
|
||||
ICELogError(<< "Cannot open file to play");
|
||||
return;
|
||||
}
|
||||
|
||||
// Delegate processing to existing audio device pair manager
|
||||
mTerminal->audio()->player().add(usageId, r, lm == lmLoopAudio, timelimit);
|
||||
start(usageId);
|
||||
// Delegate processing to existing audio device pair manager
|
||||
mTerminal->audio()->player().add(usageId, r, lm == lmLoopAudio, timelimit);
|
||||
start(usageId);
|
||||
}
|
||||
|
||||
void AudioManager::stopPlayFile(int usageId)
|
||||
{
|
||||
stop(usageId);
|
||||
mPlayer.release(usageId);
|
||||
stop(usageId);
|
||||
mPlayer.release(usageId);
|
||||
}
|
||||
|
||||
void AudioManager::onFilePlayed(Audio::Player::PlaylistItem& item)
|
||||
|
|
@ -198,9 +198,9 @@ void AudioManager::onFilePlayed(Audio::Player::PlaylistItem& item)
|
|||
|
||||
void AudioManager::process()
|
||||
{
|
||||
mPlayer.releasePlayed();
|
||||
std::vector<int> ids;
|
||||
mTerminal->audio()->player().retrieveUsageIds(ids);
|
||||
for (unsigned i=0; i<ids.size(); i++)
|
||||
stop(ids[i]);
|
||||
mPlayer.releasePlayed();
|
||||
std::vector<int> ids;
|
||||
mTerminal->audio()->player().retrieveUsageIds(ids);
|
||||
for (unsigned i=0; i<ids.size(); i++)
|
||||
stop(ids[i]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,19 +14,19 @@
|
|||
|
||||
enum
|
||||
{
|
||||
AudioPrefix_Ring = 1,
|
||||
AudioPrefix_Zero,
|
||||
AudioPrefix_One,
|
||||
AudioPrefix_Two,
|
||||
AudioPrefix_Three,
|
||||
AudioPrefix_Four,
|
||||
AudioPrefix_Five,
|
||||
AudioPrefix_Six,
|
||||
AudioPrefix_Seven,
|
||||
AudioPrefix_Eight,
|
||||
AudioPrefix_Nine,
|
||||
AudioPrefix_Asterisk,
|
||||
AudioPrefix_Diez
|
||||
AudioPrefix_Ring = 1,
|
||||
AudioPrefix_Zero,
|
||||
AudioPrefix_One,
|
||||
AudioPrefix_Two,
|
||||
AudioPrefix_Three,
|
||||
AudioPrefix_Four,
|
||||
AudioPrefix_Five,
|
||||
AudioPrefix_Six,
|
||||
AudioPrefix_Seven,
|
||||
AudioPrefix_Eight,
|
||||
AudioPrefix_Nine,
|
||||
AudioPrefix_Asterisk,
|
||||
AudioPrefix_Diez
|
||||
};
|
||||
|
||||
#define AudioSessionCoeff 64
|
||||
|
|
@ -34,56 +34,56 @@ enum
|
|||
class AudioManager: public Audio::Player::EndOfAudioDelegate
|
||||
{
|
||||
public:
|
||||
AudioManager();
|
||||
virtual ~AudioManager();
|
||||
|
||||
static AudioManager& instance();
|
||||
|
||||
// Enforces to close audio devices. Used to shutdown AudioManager on exit from application
|
||||
void close();
|
||||
AudioManager();
|
||||
virtual ~AudioManager();
|
||||
|
||||
// Terminal and settings must be available for AudioManager
|
||||
void setTerminal(MT::Terminal* terminal);
|
||||
MT::Terminal* terminal();
|
||||
static AudioManager& instance();
|
||||
|
||||
void setAudioMonitoring(Audio::DataConnection* monitoring);
|
||||
Audio::DataConnection* audioMonitoring();
|
||||
// Enforces to close audio devices. Used to shutdown AudioManager on exit from application
|
||||
void close();
|
||||
|
||||
// Start/stop methods relies on usage counter; only first start and last stop opens/closes devices actually
|
||||
void start(int usageId);
|
||||
void stop(int usageId);
|
||||
|
||||
enum AudioTarget
|
||||
{
|
||||
atNull,
|
||||
atReceiver,
|
||||
atRinger
|
||||
};
|
||||
// Terminal and settings must be available for AudioManager
|
||||
void setTerminal(MT::Terminal* terminal);
|
||||
MT::Terminal* terminal();
|
||||
|
||||
enum LoopMode
|
||||
{
|
||||
lmLoopAudio,
|
||||
lmNoloop
|
||||
};
|
||||
void setAudioMonitoring(Audio::DataConnection* monitoring);
|
||||
Audio::DataConnection* audioMonitoring();
|
||||
|
||||
void startPlayFile(int usageId, const std::string& path, AudioTarget target, LoopMode lm, int timelimit = 0);
|
||||
void stopPlayFile(int usageId);
|
||||
|
||||
// Start/stop methods relies on usage counter; only first start and last stop opens/closes devices actually
|
||||
void start(int usageId);
|
||||
void stop(int usageId);
|
||||
|
||||
void onFilePlayed(Audio::Player::PlaylistItem& item);
|
||||
|
||||
// Must be called from main loop to release used audio devices
|
||||
void process();
|
||||
enum AudioTarget
|
||||
{
|
||||
atNull,
|
||||
atReceiver,
|
||||
atRinger
|
||||
};
|
||||
|
||||
enum LoopMode
|
||||
{
|
||||
lmLoopAudio,
|
||||
lmNoloop
|
||||
};
|
||||
|
||||
void startPlayFile(int usageId, const std::string& path, AudioTarget target, LoopMode lm, int timelimit = 0);
|
||||
void stopPlayFile(int usageId);
|
||||
|
||||
|
||||
void onFilePlayed(Audio::Player::PlaylistItem& item);
|
||||
|
||||
// Must be called from main loop to release used audio devices
|
||||
void process();
|
||||
|
||||
protected:
|
||||
Audio::PInputDevice mAudioInput;
|
||||
Audio::POutputDevice mAudioOutput;
|
||||
Audio::Player mPlayer;
|
||||
MT::Terminal* mTerminal;
|
||||
Audio::DataConnection* mAudioMonitoring;
|
||||
Audio::PInputDevice mAudioInput;
|
||||
Audio::POutputDevice mAudioOutput;
|
||||
Audio::Player mPlayer;
|
||||
MT::Terminal* mTerminal;
|
||||
Audio::DataConnection* mAudioMonitoring;
|
||||
|
||||
std::map<int, int> UsageMap;
|
||||
UsageCounter mUsage;
|
||||
std::mutex mGuard;
|
||||
std::map<int, int> UsageMap;
|
||||
UsageCounter mUsage;
|
||||
std::mutex mGuard;
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -682,34 +682,34 @@ void AgentImpl::processUseStreamForSession(JsonCpp::Value& request, JsonCpp::Val
|
|||
}
|
||||
}
|
||||
else
|
||||
if (actionText == "write")
|
||||
if (actionText == "write")
|
||||
{
|
||||
if (path.empty())
|
||||
{
|
||||
if (path.empty())
|
||||
{
|
||||
// Turn off recording from the stream
|
||||
prov->writeFile(Audio::PWavFileWriter(), direction);
|
||||
answer["status"] = Status_Ok;
|
||||
}
|
||||
else
|
||||
{
|
||||
Audio::PWavFileWriter writer = std::make_shared<Audio::WavFileWriter>();
|
||||
if (!writer->open(strx::makeTstring(path), AUDIO_SAMPLERATE, AUDIO_CHANNELS))
|
||||
answer["status"] = Status_FailedToOpenFile;
|
||||
else
|
||||
{
|
||||
prov->writeFile(writer, direction);
|
||||
answer["status"] = Status_Ok;
|
||||
}
|
||||
}
|
||||
// Turn off recording from the stream
|
||||
prov->writeFile(Audio::PWavFileWriter(), direction);
|
||||
answer["status"] = Status_Ok;
|
||||
}
|
||||
else
|
||||
if (actionText == "mirror")
|
||||
{
|
||||
Audio::PWavFileWriter writer = std::make_shared<Audio::WavFileWriter>();
|
||||
if (!writer->open(strx::makeTstring(path), AUDIO_SAMPLERATE, AUDIO_CHANNELS))
|
||||
answer["status"] = Status_FailedToOpenFile;
|
||||
else
|
||||
{
|
||||
prov->setupMirror(request["enable"].asBool());
|
||||
prov->writeFile(writer, direction);
|
||||
answer["status"] = Status_Ok;
|
||||
}
|
||||
else
|
||||
answer["status"] = Status_AccountNotFound;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (actionText == "mirror")
|
||||
{
|
||||
prov->setupMirror(request["enable"].asBool());
|
||||
answer["status"] = Status_Ok;
|
||||
}
|
||||
else
|
||||
answer["status"] = Status_AccountNotFound;
|
||||
}
|
||||
else
|
||||
answer["status"] = Status_NoMediaAction;
|
||||
|
|
|
|||
|
|
@ -66,10 +66,10 @@ std::string WavFileReader::readChunk()
|
|||
if (result == "fact")
|
||||
fread(&mDataLength, 4, 1, mHandle);
|
||||
else
|
||||
if (result != "data")
|
||||
fseek(mHandle, size, SEEK_CUR);
|
||||
else
|
||||
mDataLength = size;
|
||||
if (result != "data")
|
||||
fseek(mHandle, size, SEEK_CUR);
|
||||
else
|
||||
mDataLength = size;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,23 +17,23 @@
|
|||
namespace Audio
|
||||
{
|
||||
|
||||
class WavFileReader
|
||||
{
|
||||
protected:
|
||||
class WavFileReader
|
||||
{
|
||||
protected:
|
||||
FILE* mHandle;
|
||||
uint16_t mChannels;
|
||||
uint16_t mBits;
|
||||
int mSamplerate;
|
||||
std::tstring mFileName;
|
||||
mutable std::recursive_mutex
|
||||
mFileMtx;
|
||||
mFileMtx;
|
||||
size_t mDataOffset;
|
||||
size_t mDataLength;
|
||||
Resampler mResampler;
|
||||
unsigned mLastError;
|
||||
|
||||
std::string readChunk();
|
||||
public:
|
||||
public:
|
||||
WavFileReader();
|
||||
~WavFileReader();
|
||||
|
||||
|
|
@ -56,24 +56,24 @@ namespace Audio
|
|||
size_t size() const;
|
||||
|
||||
unsigned lastError() const;
|
||||
};
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<WavFileReader> PWavFileReader;
|
||||
typedef std::shared_ptr<WavFileReader> PWavFileReader;
|
||||
|
||||
class WavFileWriter
|
||||
{
|
||||
protected:
|
||||
class WavFileWriter
|
||||
{
|
||||
protected:
|
||||
FILE* mHandle; /// Handle of audio file.
|
||||
std::tstring mFileName; /// Path to requested audio file.
|
||||
std::recursive_mutex mFileMtx; /// Mutex to protect this instance.
|
||||
size_t mWritten; /// Amount of written data (in bytes)
|
||||
size_t mLengthOffset; /// Position of length field.
|
||||
int mRate,
|
||||
mChannels;
|
||||
mChannels;
|
||||
|
||||
void checkWriteResult(int result);
|
||||
|
||||
public:
|
||||
public:
|
||||
WavFileWriter();
|
||||
~WavFileWriter();
|
||||
|
||||
|
|
@ -82,9 +82,9 @@ namespace Audio
|
|||
bool isOpened();
|
||||
size_t write(const void* buffer, size_t bytes);
|
||||
std::tstring filename();
|
||||
};
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<WavFileWriter> PWavFileWriter;
|
||||
typedef std::shared_ptr<WavFileWriter> PWavFileWriter;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -24,118 +24,118 @@ class Session;
|
|||
|
||||
class Account: public resip::DnsResultSink
|
||||
{
|
||||
friend class UserAgent;
|
||||
friend class NATDecorator;
|
||||
friend class UserAgent;
|
||||
friend class NATDecorator;
|
||||
public:
|
||||
Account(PVariantMap config, UserAgent& agent);
|
||||
~Account();
|
||||
Account(PVariantMap config, UserAgent& agent);
|
||||
~Account();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void refresh();
|
||||
bool active();
|
||||
int id() const;
|
||||
void start();
|
||||
void stop();
|
||||
void refresh();
|
||||
bool active();
|
||||
int id() const;
|
||||
|
||||
enum class RegistrationState
|
||||
{
|
||||
None,
|
||||
Registering,
|
||||
Reregistering,
|
||||
Registered,
|
||||
Unregistering
|
||||
};
|
||||
RegistrationState registrationState();
|
||||
enum class RegistrationState
|
||||
{
|
||||
None,
|
||||
Registering,
|
||||
Reregistering,
|
||||
Registered,
|
||||
Unregistering
|
||||
};
|
||||
RegistrationState registrationState();
|
||||
|
||||
/* Publishes new presence information */
|
||||
void publishPresence(bool online, const std::string& content, int seconds = 600);
|
||||
/* Publishes new presence information */
|
||||
void publishPresence(bool online, const std::string& content, int seconds = 600);
|
||||
|
||||
/* Stops publishing of presence */
|
||||
void stopPublish();
|
||||
/* Stops publishing of presence */
|
||||
void stopPublish();
|
||||
|
||||
/* Starts observing on specified target / package */
|
||||
PClientObserver observe(const std::string& target, const std::string& package, void* tag);
|
||||
/* Starts observing on specified target / package */
|
||||
PClientObserver observe(const std::string& target, const std::string& package, void* tag);
|
||||
|
||||
/* Queues message to peer with specified mime type. Returns ID of message. */
|
||||
int sendMsg(const std::string& peer, const void* ptr, unsigned length, const std::string& mime, void* tag);
|
||||
/* Queues message to peer with specified mime type. Returns ID of message. */
|
||||
int sendMsg(const std::string& peer, const void* ptr, unsigned length, const std::string& mime, void* tag);
|
||||
|
||||
/* Returns name of account - <sip:user@domain> */
|
||||
std::string name();
|
||||
/* Returns name of account - <sip:user@domain> */
|
||||
std::string name();
|
||||
|
||||
/* Updates account with configuration */
|
||||
void setup(VariantMap& config);
|
||||
/* Updates account with configuration */
|
||||
void setup(VariantMap& config);
|
||||
|
||||
/* Returns corresponding resiprocate profile */
|
||||
std::shared_ptr<resip::UserProfile> getUserProfile() const { return mProfile; }
|
||||
/* Returns corresponding resiprocate profile */
|
||||
std::shared_ptr<resip::UserProfile> getUserProfile() const { return mProfile; }
|
||||
|
||||
typedef std::map<std::string, std::string> UserInfo;
|
||||
void setUserInfo(const UserInfo& info);
|
||||
UserInfo getUserInfo() const;
|
||||
typedef std::map<std::string, std::string> UserInfo;
|
||||
void setUserInfo(const UserInfo& info);
|
||||
UserInfo getUserInfo() const;
|
||||
|
||||
protected:
|
||||
PVariantMap mConfig;
|
||||
PVariantMap mConfig;
|
||||
|
||||
// Registration
|
||||
ResipSession* mRegistration;
|
||||
resip::ClientRegistrationHandle mRegistrationHandle;
|
||||
resip::ClientPublicationHandle mPublication;
|
||||
resip::TransportType mUsedTransport;
|
||||
// Registration
|
||||
ResipSession* mRegistration;
|
||||
resip::ClientRegistrationHandle mRegistrationHandle;
|
||||
resip::ClientPublicationHandle mPublication;
|
||||
resip::TransportType mUsedTransport;
|
||||
|
||||
RegistrationState mRegistrationState;
|
||||
RegistrationState mRegistrationState;
|
||||
|
||||
ice::NetworkAddress mExternalAddress;
|
||||
std::shared_ptr<resip::UserProfile> mProfile;
|
||||
UserAgent& mAgent;
|
||||
bool mPresenceOnline;
|
||||
std::string mPresenceContent;
|
||||
ice::NetworkAddress mExternalAddress;
|
||||
std::shared_ptr<resip::UserProfile> mProfile;
|
||||
UserAgent& mAgent;
|
||||
bool mPresenceOnline;
|
||||
std::string mPresenceContent;
|
||||
|
||||
// Timer to refresh STUN server IP
|
||||
ice::ICEScheduleTimer mRefreshStunServerIpTimer;
|
||||
// Timer to refresh STUN server IP
|
||||
ice::ICEScheduleTimer mRefreshStunServerIpTimer;
|
||||
|
||||
// Cached auth
|
||||
resip::Auth mCachedAuth;
|
||||
// Cached auth
|
||||
resip::Auth mCachedAuth;
|
||||
|
||||
// Id of account
|
||||
int mId;
|
||||
// Id of account
|
||||
int mId;
|
||||
|
||||
// User info about current state
|
||||
UserInfo mUserInfo;
|
||||
// User info about current state
|
||||
UserInfo mUserInfo;
|
||||
|
||||
// List of client subscriptions sent from this account
|
||||
typedef std::set<PClientObserver> ClientObserverSet;
|
||||
ClientObserverSet mClientObserverSet;
|
||||
// List of client subscriptions sent from this account
|
||||
typedef std::set<PClientObserver> ClientObserverSet;
|
||||
ClientObserverSet mClientObserverSet;
|
||||
|
||||
|
||||
void process();
|
||||
// Method queries new stun server ip from dns (if stun server is specified as dns name)
|
||||
void queryStunServerIp();
|
||||
void process();
|
||||
// Method queries new stun server ip from dns (if stun server is specified as dns name)
|
||||
void queryStunServerIp();
|
||||
|
||||
bool isResponsibleFor(const resip::NameAddr& addr);
|
||||
enum class SecureScheme
|
||||
{
|
||||
SipsAndTls,
|
||||
SipsOnly,
|
||||
TlsOnly,
|
||||
Nothing
|
||||
};
|
||||
bool isResponsibleFor(const resip::NameAddr& addr);
|
||||
enum class SecureScheme
|
||||
{
|
||||
SipsAndTls,
|
||||
SipsOnly,
|
||||
TlsOnly,
|
||||
Nothing
|
||||
};
|
||||
|
||||
resip::NameAddr contact(SecureScheme ss = SecureScheme::SipsOnly);
|
||||
resip::NameAddr contact(SecureScheme ss = SecureScheme::SipsOnly);
|
||||
|
||||
// This method prepares configuration, creates ice stack and sets ownership to session
|
||||
void prepareIceStack(Session* session, ice::AgentRole role);
|
||||
void onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
void onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
void onFailure(resip::ClientRegistrationHandle, const resip::SipMessage& response);
|
||||
// This method prepares configuration, creates ice stack and sets ownership to session
|
||||
void prepareIceStack(Session* session, ice::AgentRole role);
|
||||
void onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
void onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
void onFailure(resip::ClientRegistrationHandle, const resip::SipMessage& response);
|
||||
|
||||
#pragma region DnsResultSink implementation
|
||||
void onDnsResult(const resip::DNSResult<resip::DnsHostRecord>&);
|
||||
void onDnsResult(const resip::DNSResult<resip::DnsAAAARecord>&);
|
||||
void onDnsResult(const resip::DNSResult<resip::DnsSrvRecord>&);
|
||||
void onDnsResult(const resip::DNSResult<resip::DnsNaptrRecord>&);
|
||||
void onDnsResult(const resip::DNSResult<resip::DnsCnameRecord>&);
|
||||
void onDnsResult(const resip::DNSResult<resip::DnsHostRecord>&);
|
||||
void onDnsResult(const resip::DNSResult<resip::DnsAAAARecord>&);
|
||||
void onDnsResult(const resip::DNSResult<resip::DnsSrvRecord>&);
|
||||
void onDnsResult(const resip::DNSResult<resip::DnsNaptrRecord>&);
|
||||
void onDnsResult(const resip::DNSResult<resip::DnsCnameRecord>&);
|
||||
#pragma endregion
|
||||
|
||||
static int generateId();
|
||||
static std::atomic_int IdGenerator;
|
||||
static int generateId();
|
||||
static std::atomic_int IdGenerator;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Account> PAccount;
|
||||
|
|
|
|||
|
|
@ -8,67 +8,67 @@
|
|||
|
||||
bool DataProvider::isSupported(const char* name)
|
||||
{
|
||||
return !strcmp(name, "audio");
|
||||
return !strcmp(name, "audio");
|
||||
|
||||
//return (!strcmp(name, "screen") || !strcmp(name, "data") || !strcmp(name, "audio") || !strcmp(name, "video"));
|
||||
//return (!strcmp(name, "screen") || !strcmp(name, "data") || !strcmp(name, "audio") || !strcmp(name, "video"));
|
||||
}
|
||||
|
||||
void DataProvider::pause()
|
||||
{
|
||||
/*if (state() & STATE_SIPRECV)
|
||||
/*if (state() & STATE_SIPRECV)
|
||||
setState( state() & ~STATE_SIPRECV );*/
|
||||
|
||||
// Stop receive RTP stream
|
||||
if (state() & (int)StreamState::Receiving)
|
||||
setState( state() & ~(int)StreamState::Receiving );
|
||||
|
||||
mActive = mfPaused;
|
||||
// Stop receive RTP stream
|
||||
if (state() & (int)StreamState::Receiving)
|
||||
setState( state() & ~(int)StreamState::Receiving );
|
||||
|
||||
mActive = mfPaused;
|
||||
}
|
||||
|
||||
void DataProvider::resume()
|
||||
{
|
||||
// Tell remote peer about resumed receiving in SDP
|
||||
//setState( state() | STATE_SIPRECV );
|
||||
// Tell remote peer about resumed receiving in SDP
|
||||
//setState( state() | STATE_SIPRECV );
|
||||
|
||||
// Start receive RTP stream
|
||||
setState( state() | (int)StreamState::Receiving );
|
||||
|
||||
mActive = mfActive;
|
||||
// Start receive RTP stream
|
||||
setState( state() | (int)StreamState::Receiving );
|
||||
|
||||
mActive = mfActive;
|
||||
}
|
||||
|
||||
bool DataProvider::processSdpOffer(const resip::SdpContents::Session::Medium& media, SdpDirection sdpDirection)
|
||||
{
|
||||
// Process paused and inactive calls
|
||||
if (media.exists("sendonly"))
|
||||
{
|
||||
mRemoteState = msSendonly;
|
||||
setState(state() & ~(int)StreamState::Sending);
|
||||
}
|
||||
else
|
||||
if (media.exists("recvonly"))
|
||||
{
|
||||
mRemoteState = msRecvonly;
|
||||
setState(state() & ~(int)StreamState::Receiving);
|
||||
}
|
||||
else
|
||||
if (media.exists("inactive"))
|
||||
{
|
||||
mRemoteState = msInactive;
|
||||
setState(state() & ~((int)StreamState::Sending | (int)StreamState::Receiving) );
|
||||
}
|
||||
else
|
||||
{
|
||||
mRemoteState = msSendRecv;
|
||||
switch (mActive)
|
||||
// Process paused and inactive calls
|
||||
if (media.exists("sendonly"))
|
||||
{
|
||||
case mfActive:
|
||||
setState(state() | (int)StreamState::Sending | (int)StreamState::Receiving);
|
||||
break;
|
||||
|
||||
case mfPaused:
|
||||
setState(state() | (int)StreamState::Sending );
|
||||
break;
|
||||
mRemoteState = msSendonly;
|
||||
setState(state() & ~(int)StreamState::Sending);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
else
|
||||
if (media.exists("recvonly"))
|
||||
{
|
||||
mRemoteState = msRecvonly;
|
||||
setState(state() & ~(int)StreamState::Receiving);
|
||||
}
|
||||
else
|
||||
if (media.exists("inactive"))
|
||||
{
|
||||
mRemoteState = msInactive;
|
||||
setState(state() & ~((int)StreamState::Sending | (int)StreamState::Receiving) );
|
||||
}
|
||||
else
|
||||
{
|
||||
mRemoteState = msSendRecv;
|
||||
switch (mActive)
|
||||
{
|
||||
case mfActive:
|
||||
setState(state() | (int)StreamState::Sending | (int)StreamState::Receiving);
|
||||
break;
|
||||
|
||||
case mfPaused:
|
||||
setState(state() | (int)StreamState::Sending );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,70 +19,70 @@
|
|||
class DataProvider
|
||||
{
|
||||
public:
|
||||
enum MediaFlow
|
||||
{
|
||||
mfActive,
|
||||
mfPaused
|
||||
};
|
||||
|
||||
enum MediaState
|
||||
{
|
||||
msSendRecv,
|
||||
msSendonly,
|
||||
msRecvonly,
|
||||
msInactive
|
||||
};
|
||||
enum MediaFlow
|
||||
{
|
||||
mfActive,
|
||||
mfPaused
|
||||
};
|
||||
|
||||
static bool isSupported(const char* name);
|
||||
enum MediaState
|
||||
{
|
||||
msSendRecv,
|
||||
msSendonly,
|
||||
msRecvonly,
|
||||
msInactive
|
||||
};
|
||||
|
||||
// Returns provider RTP name
|
||||
virtual std::string streamName() = 0;
|
||||
|
||||
// Returns provider RTP profile name
|
||||
virtual std::string streamProfile() = 0;
|
||||
|
||||
// Sets destination IP address
|
||||
virtual void setDestinationAddress(const RtpPair<InternetAddress>& addr) = 0;
|
||||
static bool isSupported(const char* name);
|
||||
|
||||
// Processes incoming data
|
||||
virtual void processData(const PDatagramSocket& s, const void* dataBuffer, int dataSize, InternetAddress& address) = 0;
|
||||
// Returns provider RTP name
|
||||
virtual std::string streamName() = 0;
|
||||
|
||||
// This method is called by user agent to send ICE packet from mediasocket
|
||||
virtual void sendData(const PDatagramSocket& s, InternetAddress& destination, const void* dataBuffer, unsigned int datasize) = 0;
|
||||
|
||||
// Updates SDP offer
|
||||
virtual void updateSdpOffer(resip::SdpContents::Session::Medium& sdp, SdpDirection direction) = 0;
|
||||
// Returns provider RTP profile name
|
||||
virtual std::string streamProfile() = 0;
|
||||
|
||||
// Called by user agent when session is deleted. Comes after sessionTerminated().
|
||||
virtual void sessionDeleted() = 0;
|
||||
// Sets destination IP address
|
||||
virtual void setDestinationAddress(const RtpPair<InternetAddress>& addr) = 0;
|
||||
|
||||
// Called by user agent when session is terminated.
|
||||
virtual void sessionTerminated() = 0;
|
||||
// Processes incoming data
|
||||
virtual void processData(const PDatagramSocket& s, const void* dataBuffer, int dataSize, InternetAddress& address) = 0;
|
||||
|
||||
// Called by user agent when session is started.
|
||||
virtual void sessionEstablished(int conntype) = 0;
|
||||
// This method is called by user agent to send ICE packet from mediasocket
|
||||
virtual void sendData(const PDatagramSocket& s, InternetAddress& destination, const void* dataBuffer, unsigned int datasize) = 0;
|
||||
|
||||
// Called by user agent to save media socket for this provider
|
||||
virtual void setSocket(const RtpPair<PDatagramSocket>& p4, const RtpPair<PDatagramSocket>& p6) = 0;
|
||||
|
||||
// Called by user agent to get media socket for this provider
|
||||
virtual RtpPair<PDatagramSocket>& socket(int family) = 0;
|
||||
// Updates SDP offer
|
||||
virtual void updateSdpOffer(resip::SdpContents::Session::Medium& sdp, SdpDirection direction) = 0;
|
||||
|
||||
// Called by user agent to process media stream description from remote peer.
|
||||
// Returns true if description is processed succesfully. Otherwise method returns false.
|
||||
virtual bool processSdpOffer(const resip::SdpContents::Session::Medium& media, SdpDirection sdpDirection) = 0;
|
||||
|
||||
virtual unsigned state() = 0;
|
||||
virtual void setState(unsigned state) = 0;
|
||||
|
||||
virtual void pause();
|
||||
virtual void resume();
|
||||
// Called by user agent when session is deleted. Comes after sessionTerminated().
|
||||
virtual void sessionDeleted() = 0;
|
||||
|
||||
virtual MT::Statistics getStatistics() = 0;
|
||||
// Called by user agent when session is terminated.
|
||||
virtual void sessionTerminated() = 0;
|
||||
|
||||
// Called by user agent when session is started.
|
||||
virtual void sessionEstablished(int conntype) = 0;
|
||||
|
||||
// Called by user agent to save media socket for this provider
|
||||
virtual void setSocket(const RtpPair<PDatagramSocket>& p4, const RtpPair<PDatagramSocket>& p6) = 0;
|
||||
|
||||
// Called by user agent to get media socket for this provider
|
||||
virtual RtpPair<PDatagramSocket>& socket(int family) = 0;
|
||||
|
||||
// Called by user agent to process media stream description from remote peer.
|
||||
// Returns true if description is processed succesfully. Otherwise method returns false.
|
||||
virtual bool processSdpOffer(const resip::SdpContents::Session::Medium& media, SdpDirection sdpDirection) = 0;
|
||||
|
||||
virtual unsigned state() = 0;
|
||||
virtual void setState(unsigned state) = 0;
|
||||
|
||||
virtual void pause();
|
||||
virtual void resume();
|
||||
|
||||
virtual MT::Statistics getStatistics() = 0;
|
||||
|
||||
protected:
|
||||
MediaFlow mActive;
|
||||
MediaState mRemoteState;
|
||||
MediaFlow mActive;
|
||||
MediaState mRemoteState;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<DataProvider> PDataProvider;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -70,52 +70,52 @@ enum
|
|||
|
||||
enum
|
||||
{
|
||||
CONFIG_IPV4 = 0, // Use IP4
|
||||
CONFIG_IPV6, // Use IP6.
|
||||
CONFIG_USERNAME, // Username. String value.
|
||||
CONFIG_DOMAIN, // Domain. String value.
|
||||
CONFIG_PASSWORD, // Password. String value.
|
||||
CONFIG_RINSTANCE, // Determines if SIP rinstance field has to be used during registration. Boolean value.
|
||||
CONFIG_INSTANCE_ID, // Instance id. It is alternative option to rinstance.
|
||||
CONFIG_DISPLAYNAME, // Optional user display name. String value.
|
||||
CONFIG_DOMAINPORT, // Optional domain port number. Integer value.
|
||||
CONFIG_REGISTERDURATION, // Wanted duration for registration. Integer value. It is MANDATORY value.
|
||||
CONFIG_RPORT, // Use SIP rport field. Recommended to set it to true. Boolean value.
|
||||
CONFIG_KEEPALIVETIME, // Interval between UDP keep-alive messages. Boolean value.
|
||||
CONFIG_RELAY, // Sets if TURN server must be used instead of STUN. Boolean value.
|
||||
CONFIG_ICETIMEOUT, // Optional timeout for ICE connectivity checks and candidate gathering. Integer value.
|
||||
CONFIG_ICEUSERNAME, // Optional username for TURN server. String value.
|
||||
CONFIG_ICEPASSWORD, // Optional password for TURN server. String value.
|
||||
CONFIG_SIPS, // Marks if account credentials are sips: scheme. Boolean value.
|
||||
CONFIG_STUNSERVER_IP, // Optional IP address of STUN/TURN server. String value. It is better to use CONFIG_STUNSERVER_NAME.
|
||||
CONFIG_STUNSERVER_NAME, // Host name of STUN/TURN server. stun.xten.com for example. String value.
|
||||
CONFIG_STUNSERVER_PORT, // Port number of STUN/TURN server. Integer value.
|
||||
CONFIG_USERAGENT, // Name of user agent in SIP headers. String value.
|
||||
CONFIG_ICEREQUIRED, // ICE MUST be present in remote peer offers and answers. Boolean value.
|
||||
CONFIG_TRANSPORT, // 0 - all transports, 1 - UDP, 2 - TCP, 3 - TLS,
|
||||
CONFIG_SUBSCRIPTION_TIME, // Subscription time (in seconds)
|
||||
CONFIG_SUBSCRIPTION_REFRESHTIME, // Refresh interval for subscriptions
|
||||
CONFIG_DNS_CACHE_TIME, // DNS cache time; default is 86400 seconds
|
||||
CONFIG_PRESENCE_ID, // Tuple ID used in presence publishing; determines source device
|
||||
CONFIG_ROOTCERT, // Additional root cert in PEM format; string.
|
||||
CONFIG_CACHECREDENTIALS, // Attempt to cache credentials that comes in response from PBX. Use them when possible to reduce number of steps of SIP transaction
|
||||
CONFIG_RTCP_ATTR, // Use "rtcp" attribute in sdp. Default value is true.
|
||||
CONFIG_MULTIPLEXING, // Do rtp/rtcp multiplexing
|
||||
CONFIG_DEFERRELAYED, // Defer relayed media path
|
||||
CONFIG_PROXY, // Proxy host name or IP address
|
||||
CONFIG_PROXYPORT, // Proxy port number
|
||||
CONFIG_CODEC_PRIORITY, // Another VariantMap with codec priorities,
|
||||
CONFIG_ACCOUNT, // VariantMap with account configuration
|
||||
CONFIG_EXTERNALIP, // Use external/public IP in outgoing requests
|
||||
CONFIG_OWN_DNS, // Use predefined DNS servers
|
||||
CONFIG_REGID // reg-id value from RFC5626
|
||||
CONFIG_IPV4 = 0, // Use IP4
|
||||
CONFIG_IPV6, // Use IP6.
|
||||
CONFIG_USERNAME, // Username. String value.
|
||||
CONFIG_DOMAIN, // Domain. String value.
|
||||
CONFIG_PASSWORD, // Password. String value.
|
||||
CONFIG_RINSTANCE, // Determines if SIP rinstance field has to be used during registration. Boolean value.
|
||||
CONFIG_INSTANCE_ID, // Instance id. It is alternative option to rinstance.
|
||||
CONFIG_DISPLAYNAME, // Optional user display name. String value.
|
||||
CONFIG_DOMAINPORT, // Optional domain port number. Integer value.
|
||||
CONFIG_REGISTERDURATION, // Wanted duration for registration. Integer value. It is MANDATORY value.
|
||||
CONFIG_RPORT, // Use SIP rport field. Recommended to set it to true. Boolean value.
|
||||
CONFIG_KEEPALIVETIME, // Interval between UDP keep-alive messages. Boolean value.
|
||||
CONFIG_RELAY, // Sets if TURN server must be used instead of STUN. Boolean value.
|
||||
CONFIG_ICETIMEOUT, // Optional timeout for ICE connectivity checks and candidate gathering. Integer value.
|
||||
CONFIG_ICEUSERNAME, // Optional username for TURN server. String value.
|
||||
CONFIG_ICEPASSWORD, // Optional password for TURN server. String value.
|
||||
CONFIG_SIPS, // Marks if account credentials are sips: scheme. Boolean value.
|
||||
CONFIG_STUNSERVER_IP, // Optional IP address of STUN/TURN server. String value. It is better to use CONFIG_STUNSERVER_NAME.
|
||||
CONFIG_STUNSERVER_NAME, // Host name of STUN/TURN server. stun.xten.com for example. String value.
|
||||
CONFIG_STUNSERVER_PORT, // Port number of STUN/TURN server. Integer value.
|
||||
CONFIG_USERAGENT, // Name of user agent in SIP headers. String value.
|
||||
CONFIG_ICEREQUIRED, // ICE MUST be present in remote peer offers and answers. Boolean value.
|
||||
CONFIG_TRANSPORT, // 0 - all transports, 1 - UDP, 2 - TCP, 3 - TLS,
|
||||
CONFIG_SUBSCRIPTION_TIME, // Subscription time (in seconds)
|
||||
CONFIG_SUBSCRIPTION_REFRESHTIME, // Refresh interval for subscriptions
|
||||
CONFIG_DNS_CACHE_TIME, // DNS cache time; default is 86400 seconds
|
||||
CONFIG_PRESENCE_ID, // Tuple ID used in presence publishing; determines source device
|
||||
CONFIG_ROOTCERT, // Additional root cert in PEM format; string.
|
||||
CONFIG_CACHECREDENTIALS, // Attempt to cache credentials that comes in response from PBX. Use them when possible to reduce number of steps of SIP transaction
|
||||
CONFIG_RTCP_ATTR, // Use "rtcp" attribute in sdp. Default value is true.
|
||||
CONFIG_MULTIPLEXING, // Do rtp/rtcp multiplexing
|
||||
CONFIG_DEFERRELAYED, // Defer relayed media path
|
||||
CONFIG_PROXY, // Proxy host name or IP address
|
||||
CONFIG_PROXYPORT, // Proxy port number
|
||||
CONFIG_CODEC_PRIORITY, // Another VariantMap with codec priorities,
|
||||
CONFIG_ACCOUNT, // VariantMap with account configuration
|
||||
CONFIG_EXTERNALIP, // Use external/public IP in outgoing requests
|
||||
CONFIG_OWN_DNS, // Use predefined DNS servers
|
||||
CONFIG_REGID // reg-id value from RFC5626
|
||||
};
|
||||
|
||||
// Conntype parameter for OnSessionEstablished event
|
||||
enum
|
||||
{
|
||||
EV_SIP = 1,
|
||||
EV_ICE = 2
|
||||
EV_SIP = 1,
|
||||
EV_ICE = 2
|
||||
};
|
||||
|
||||
class UserAgent;
|
||||
|
|
@ -124,7 +124,7 @@ class UserAgent;
|
|||
class SIPAction
|
||||
{
|
||||
public:
|
||||
virtual void Run(UserAgent& ua) = 0;
|
||||
virtual void Run(UserAgent& ua) = 0;
|
||||
};
|
||||
|
||||
typedef std::vector<SIPAction*> SIPActionVector;
|
||||
|
|
@ -132,15 +132,15 @@ typedef std::vector<SIPAction*> SIPActionVector;
|
|||
// Session termination reason
|
||||
enum
|
||||
{
|
||||
Error,
|
||||
Timeout,
|
||||
Replaced,
|
||||
LocalBye,
|
||||
RemoteBye,
|
||||
LocalCancel,
|
||||
RemoteCancel,
|
||||
Rejected, //Only as UAS, UAC has distinct onFailure callback
|
||||
Referred
|
||||
Error,
|
||||
Timeout,
|
||||
Replaced,
|
||||
LocalBye,
|
||||
RemoteBye,
|
||||
LocalCancel,
|
||||
RemoteCancel,
|
||||
Rejected, //Only as UAS, UAC has distinct onFailure callback
|
||||
Referred
|
||||
};
|
||||
|
||||
class UserAgent: public resip::ClientRegistrationHandler,
|
||||
|
|
@ -153,238 +153,238 @@ class UserAgent: public resip::ClientRegistrationHandler,
|
|||
public resip::ClientPagerMessageHandler,
|
||||
public resip::ServerPagerMessageHandler,
|
||||
public resip::ClientPublicationHandler
|
||||
//public resip::InternalTransport::TransportLogger
|
||||
//public resip::InternalTransport::TransportLogger
|
||||
{
|
||||
friend class Account;
|
||||
friend class Session;
|
||||
friend class ResipSession;
|
||||
friend class NATDecorator;
|
||||
friend class WatcherQueue;
|
||||
friend class Account;
|
||||
friend class Session;
|
||||
friend class ResipSession;
|
||||
friend class NATDecorator;
|
||||
friend class WatcherQueue;
|
||||
public:
|
||||
/* Compares two sip addresses. Returns true if they represent the same entity - user and domain are the same. Otherwise returns false. */
|
||||
static bool compareSipAddresses(const std::string& sip1, const std::string& sip2);
|
||||
static std::string formatSipAddress(const std::string& sip);
|
||||
static bool isSipAddressValid(const std::string& sip);
|
||||
struct SipAddress
|
||||
{
|
||||
bool mValid;
|
||||
std::string mScheme;
|
||||
std::string mUsername;
|
||||
std::string mDomain;
|
||||
std::string mDisplayname;
|
||||
};
|
||||
/* Compares two sip addresses. Returns true if they represent the same entity - user and domain are the same. Otherwise returns false. */
|
||||
static bool compareSipAddresses(const std::string& sip1, const std::string& sip2);
|
||||
static std::string formatSipAddress(const std::string& sip);
|
||||
static bool isSipAddressValid(const std::string& sip);
|
||||
struct SipAddress
|
||||
{
|
||||
bool mValid;
|
||||
std::string mScheme;
|
||||
std::string mUsername;
|
||||
std::string mDomain;
|
||||
std::string mDisplayname;
|
||||
};
|
||||
|
||||
static SipAddress parseSipAddress(const std::string& sip);
|
||||
static SipAddress parseSipAddress(const std::string& sip);
|
||||
|
||||
UserAgent();
|
||||
virtual ~UserAgent();
|
||||
|
||||
/* Brings user agent online. Basically it creates a signalling socket(s).
|
||||
UserAgent();
|
||||
virtual ~UserAgent();
|
||||
|
||||
/* Brings user agent online. Basically it creates a signalling socket(s).
|
||||
This is asynchronous method. */
|
||||
void start();
|
||||
|
||||
/* Shutdowns user agent. It closes all sessions, tries to unregister from server and disconnects from it.
|
||||
void start();
|
||||
|
||||
/* Shutdowns user agent. It closes all sessions, tries to unregister from server and disconnects from it.
|
||||
This is asynchronous method. onStop() event will be called later */
|
||||
void shutdown();
|
||||
|
||||
/* Emergency stop. Please always call shutdown() before this. Kills registration, sessions & presence - everything. onStop() is called in context of this method. */
|
||||
void stop();
|
||||
void shutdown();
|
||||
|
||||
/* Checks if user agent is active (started). */
|
||||
bool active();
|
||||
|
||||
/* Used to refresh existing registration(s), publication, subscriptions. */
|
||||
void refresh();
|
||||
/* Emergency stop. Please always call shutdown() before this. Kills registration, sessions & presence - everything. onStop() is called in context of this method. */
|
||||
void stop();
|
||||
|
||||
/* Runs sip & ice stacks. Event handlers are called in its context. */
|
||||
void process();
|
||||
|
||||
/* Adds root cert in PEM format. Usable after start() call. */
|
||||
void addRootCert(const ByteBuffer& data);
|
||||
/* Checks if user agent is active (started). */
|
||||
bool active();
|
||||
|
||||
PAccount createAccount(PVariantMap config);
|
||||
void deleteAccount(PAccount account);
|
||||
/* Used to refresh existing registration(s), publication, subscriptions. */
|
||||
void refresh();
|
||||
|
||||
/* Creates session. Returns session ID. */
|
||||
PSession createSession(PAccount account);
|
||||
|
||||
// Must be called when IP interface list is changed
|
||||
void updateInterfaceList();
|
||||
/* Runs sip & ice stacks. Event handlers are called in its context. */
|
||||
void process();
|
||||
|
||||
// Called on new incoming session; providers shoukld
|
||||
virtual PDataProvider onProviderNeeded(const std::string& name) = 0;
|
||||
/* Adds root cert in PEM format. Usable after start() call. */
|
||||
void addRootCert(const ByteBuffer& data);
|
||||
|
||||
// Called on new session offer
|
||||
virtual void onNewSession(PSession s) = 0;
|
||||
|
||||
// Called when session is terminated
|
||||
virtual void onSessionTerminated(PSession s, int responsecode, int reason) = 0;
|
||||
|
||||
// Called when session is established ok i.e. after all ICE signalling is finished
|
||||
// Conntype is type of establish event - EV_SIP or EV_ICE
|
||||
virtual void onSessionEstablished(PSession s, int conntype, const RtpPair<InternetAddress>& p) = 0;
|
||||
PAccount createAccount(PVariantMap config);
|
||||
void deleteAccount(PAccount account);
|
||||
|
||||
// Called when client session gets
|
||||
virtual void onSessionProvisional(PSession s, int code) = 0;
|
||||
/* Creates session. Returns session ID. */
|
||||
PSession createSession(PAccount account);
|
||||
|
||||
// Called when user agent started
|
||||
virtual void onStart(int errorcode) = 0;
|
||||
|
||||
// Called when user agent stopped
|
||||
virtual void onStop() = 0;
|
||||
// Must be called when IP interface list is changed
|
||||
void updateInterfaceList();
|
||||
|
||||
// Called when account registered
|
||||
virtual void onAccountStart(PAccount account) = 0;
|
||||
// Called on new incoming session; providers shoukld
|
||||
virtual PDataProvider onProviderNeeded(const std::string& name) = 0;
|
||||
|
||||
// Called when account removed or failed (non zero error code)
|
||||
virtual void onAccountStop(PAccount account, int error) = 0;
|
||||
// Called on new session offer
|
||||
virtual void onNewSession(PSession s) = 0;
|
||||
|
||||
// Called when connectivity checks failed.
|
||||
virtual void onConnectivityFailed(PSession s) = 0;
|
||||
// Called when session is terminated
|
||||
virtual void onSessionTerminated(PSession s, int responsecode, int reason) = 0;
|
||||
|
||||
// Called when new candidate is gathered
|
||||
virtual void onCandidateGathered(PSession s, const char* address);
|
||||
|
||||
// Called when network change detected
|
||||
virtual void onNetworkChange(PSession s) = 0;
|
||||
// Called when session is established ok i.e. after all ICE signalling is finished
|
||||
// Conntype is type of establish event - EV_SIP or EV_ICE
|
||||
virtual void onSessionEstablished(PSession s, int conntype, const RtpPair<InternetAddress>& p) = 0;
|
||||
|
||||
// Called when all candidates are gathered
|
||||
virtual void onGathered(PSession s);
|
||||
// Called when client session gets
|
||||
virtual void onSessionProvisional(PSession s, int code) = 0;
|
||||
|
||||
// Called when new connectivity check is finished
|
||||
virtual void onCheckFinished(PSession s, const char* description);
|
||||
|
||||
// Called when log message must be recorded
|
||||
virtual void onLog(const char* msg);
|
||||
|
||||
// Called when problem with SIP connection(s) detected
|
||||
virtual void onSipConnectionFailed() = 0;
|
||||
// Called when user agent started
|
||||
virtual void onStart(int errorcode) = 0;
|
||||
|
||||
// Subscribe/publish presence methods
|
||||
virtual void onPublicationSuccess(PAccount acc);
|
||||
virtual void onPublicationTerminated(PAccount acc, int code);
|
||||
virtual void onClientObserverStart(PClientObserver observer);
|
||||
virtual void onServerObserverStart(PServerObserver observer);
|
||||
virtual void onClientObserverStop(PClientObserver observer, int code);
|
||||
virtual void onServerObserverStop(PServerObserver observer, int code);
|
||||
// Called when user agent stopped
|
||||
virtual void onStop() = 0;
|
||||
|
||||
virtual void onPresenceUpdate(PClientObserver observer, const std::string& peer, bool online, const std::string& content);
|
||||
virtual void onMessageArrived(PAccount account, const std::string& peer, const void* ptr, unsigned length);
|
||||
virtual void onMessageFailed(PAccount account, int id, const std::string& peer, int code, void* tag);
|
||||
virtual void onMessageSent(PAccount account, int id, const std::string& peer, void* tag);
|
||||
|
||||
// Configuration methods
|
||||
VariantMap& config();
|
||||
// Called when account registered
|
||||
virtual void onAccountStart(PAccount account) = 0;
|
||||
|
||||
// Called when account removed or failed (non zero error code)
|
||||
virtual void onAccountStop(PAccount account, int error) = 0;
|
||||
|
||||
// Called when connectivity checks failed.
|
||||
virtual void onConnectivityFailed(PSession s) = 0;
|
||||
|
||||
// Called when new candidate is gathered
|
||||
virtual void onCandidateGathered(PSession s, const char* address);
|
||||
|
||||
// Called when network change detected
|
||||
virtual void onNetworkChange(PSession s) = 0;
|
||||
|
||||
// Called when all candidates are gathered
|
||||
virtual void onGathered(PSession s);
|
||||
|
||||
// Called when new connectivity check is finished
|
||||
virtual void onCheckFinished(PSession s, const char* description);
|
||||
|
||||
// Called when log message must be recorded
|
||||
virtual void onLog(const char* msg);
|
||||
|
||||
// Called when problem with SIP connection(s) detected
|
||||
virtual void onSipConnectionFailed() = 0;
|
||||
|
||||
// Subscribe/publish presence methods
|
||||
virtual void onPublicationSuccess(PAccount acc);
|
||||
virtual void onPublicationTerminated(PAccount acc, int code);
|
||||
virtual void onClientObserverStart(PClientObserver observer);
|
||||
virtual void onServerObserverStart(PServerObserver observer);
|
||||
virtual void onClientObserverStop(PClientObserver observer, int code);
|
||||
virtual void onServerObserverStop(PServerObserver observer, int code);
|
||||
|
||||
virtual void onPresenceUpdate(PClientObserver observer, const std::string& peer, bool online, const std::string& content);
|
||||
virtual void onMessageArrived(PAccount account, const std::string& peer, const void* ptr, unsigned length);
|
||||
virtual void onMessageFailed(PAccount account, int id, const std::string& peer, int code, void* tag);
|
||||
virtual void onMessageSent(PAccount account, int id, const std::string& peer, void* tag);
|
||||
|
||||
// Configuration methods
|
||||
VariantMap& config();
|
||||
|
||||
public:
|
||||
// InviteSessionHandler implementation
|
||||
// InviteSessionHandler implementation
|
||||
#pragma region InviteSessionHandler implementation
|
||||
/// called when an initial INVITE or the intial response to an outoing invite
|
||||
virtual void onNewSession(resip::ClientInviteSessionHandle, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg) override;
|
||||
virtual void onNewSession(resip::ServerInviteSessionHandle, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg) override;
|
||||
/// called when an initial INVITE or the intial response to an outoing invite
|
||||
virtual void onNewSession(resip::ClientInviteSessionHandle, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg) override;
|
||||
virtual void onNewSession(resip::ServerInviteSessionHandle, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg) override;
|
||||
|
||||
/// Received a failure response from UAS
|
||||
virtual void onFailure(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
/// called when an in-dialog provisional response is received that contains an SDP body
|
||||
virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage&, const resip::SdpContents&) override;
|
||||
/// Received a failure response from UAS
|
||||
virtual void onFailure(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
/// called when dialog enters the Early state - typically after getting 18x
|
||||
virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage&) override;
|
||||
/// called when an in-dialog provisional response is received that contains an SDP body
|
||||
virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage&, const resip::SdpContents&) override;
|
||||
|
||||
/// called when a dialog initiated as a UAC enters the connected state
|
||||
virtual void onConnected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
/// called when dialog enters the Early state - typically after getting 18x
|
||||
virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage&) override;
|
||||
|
||||
/// called when a dialog initiated as a UAS enters the connected state
|
||||
virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
/// called when a dialog initiated as a UAC enters the connected state
|
||||
virtual void onConnected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
virtual void onTerminated(resip::InviteSessionHandle, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* related=0) override;
|
||||
/// called when a dialog initiated as a UAS enters the connected state
|
||||
virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
/// called when a fork that was created through a 1xx never receives a 2xx
|
||||
/// because another fork answered and this fork was canceled by a proxy.
|
||||
virtual void onForkDestroyed(resip::ClientInviteSessionHandle) override;
|
||||
virtual void onTerminated(resip::InviteSessionHandle, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* related=0) override;
|
||||
|
||||
/// called when a 3xx with valid targets is encountered in an early dialog
|
||||
/// This is different then getting a 3xx in onTerminated, as another
|
||||
/// request will be attempted, so the DialogSet will not be destroyed.
|
||||
/// Basically an onTermintated that conveys more information.
|
||||
/// checking for 3xx respones in onTerminated will not work as there may
|
||||
/// be no valid targets.
|
||||
virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
/// called when a fork that was created through a 1xx never receives a 2xx
|
||||
/// because another fork answered and this fork was canceled by a proxy.
|
||||
virtual void onForkDestroyed(resip::ClientInviteSessionHandle) override;
|
||||
|
||||
/// called when an SDP answer is received - has nothing to do with user
|
||||
/// answering the call
|
||||
virtual void onAnswer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&) override;
|
||||
/// called when a 3xx with valid targets is encountered in an early dialog
|
||||
/// This is different then getting a 3xx in onTerminated, as another
|
||||
/// request will be attempted, so the DialogSet will not be destroyed.
|
||||
/// Basically an onTermintated that conveys more information.
|
||||
/// checking for 3xx respones in onTerminated will not work as there may
|
||||
/// be no valid targets.
|
||||
virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
/// called when an SDP offer is received - must send an answer soon after this
|
||||
virtual void onOffer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&) override;
|
||||
/// called when an SDP answer is received - has nothing to do with user
|
||||
/// answering the call
|
||||
virtual void onAnswer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&) override;
|
||||
|
||||
/// called when an Invite w/out SDP is sent, or any other context which
|
||||
/// requires an SDP offer from the user
|
||||
virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
/// called if an offer in a UPDATE or re-INVITE was rejected - not real
|
||||
/// useful. A SipMessage is provided if one is available
|
||||
virtual void onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg) override;
|
||||
|
||||
/// called when INFO message is received
|
||||
virtual void onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
/// called when an SDP offer is received - must send an answer soon after this
|
||||
virtual void onOffer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&) override;
|
||||
|
||||
/// called when response to INFO message is received
|
||||
virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
/// called when an Invite w/out SDP is sent, or any other context which
|
||||
/// requires an SDP offer from the user
|
||||
virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
/// called when MESSAGE message is received
|
||||
virtual void onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
/// called if an offer in a UPDATE or re-INVITE was rejected - not real
|
||||
/// useful. A SipMessage is provided if one is available
|
||||
virtual void onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg) override;
|
||||
|
||||
/// called when response to MESSAGE message is received
|
||||
virtual void onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
virtual void onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
/// called when INFO message is received
|
||||
virtual void onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
/// called when an REFER message is received. The refer is accepted or
|
||||
/// rejected using the server subscription. If the offer is accepted,
|
||||
/// DialogUsageManager::makeInviteSessionFromRefer can be used to create an
|
||||
/// InviteSession that will send notify messages using the ServerSubscription
|
||||
virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg) override;
|
||||
/// called when response to INFO message is received
|
||||
virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
virtual void onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
/// called when MESSAGE message is received
|
||||
virtual void onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
/// called when an REFER message receives a failure response
|
||||
virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
/// called when response to MESSAGE message is received
|
||||
virtual void onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
virtual void onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
/// called when an REFER message receives an accepted response
|
||||
virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg) override;
|
||||
/// called when an REFER message is received. The refer is accepted or
|
||||
/// rejected using the server subscription. If the offer is accepted,
|
||||
/// DialogUsageManager::makeInviteSessionFromRefer can be used to create an
|
||||
/// InviteSession that will send notify messages using the ServerSubscription
|
||||
virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
virtual void onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
/// called when an REFER message receives a failure response
|
||||
virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg) override;
|
||||
|
||||
/// called when an REFER message receives an accepted response
|
||||
virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg) override;
|
||||
#pragma endregion
|
||||
|
||||
// ClientRegistrationHandler implementation
|
||||
// ClientRegistrationHandler implementation
|
||||
#pragma region ClientRegistrationHandler implementation
|
||||
/// Called when registraion succeeds or each time it is sucessfully
|
||||
/// refreshed.
|
||||
void onSuccess(resip::ClientRegistrationHandle, const resip::SipMessage& response) override;
|
||||
/// Called when registraion succeeds or each time it is sucessfully
|
||||
/// refreshed.
|
||||
void onSuccess(resip::ClientRegistrationHandle, const resip::SipMessage& response) override;
|
||||
|
||||
// Called when all of my bindings have been removed
|
||||
void onRemoved(resip::ClientRegistrationHandle, const resip::SipMessage& response) override;
|
||||
|
||||
/// call on Retry-After failure.
|
||||
/// return values: -1 = fail, 0 = retry immediately, N = retry in N seconds
|
||||
int onRequestRetry(resip::ClientRegistrationHandle, int retrySeconds, const resip::SipMessage& response) override;
|
||||
|
||||
/// Called if registration fails, usage will be destroyed (unless a
|
||||
/// Registration retry interval is enabled in the Profile)
|
||||
void onFailure(resip::ClientRegistrationHandle, const resip::SipMessage& response) override;
|
||||
// Called when all of my bindings have been removed
|
||||
void onRemoved(resip::ClientRegistrationHandle, const resip::SipMessage& response) override;
|
||||
|
||||
/// call on Retry-After failure.
|
||||
/// return values: -1 = fail, 0 = retry immediately, N = retry in N seconds
|
||||
int onRequestRetry(resip::ClientRegistrationHandle, int retrySeconds, const resip::SipMessage& response) override;
|
||||
|
||||
/// Called if registration fails, usage will be destroyed (unless a
|
||||
/// Registration retry interval is enabled in the Profile)
|
||||
void onFailure(resip::ClientRegistrationHandle, const resip::SipMessage& response) override;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region ExternalLogger implementation
|
||||
/** return true to also do default logging, false to suppress default logging. */
|
||||
virtual bool operator()(resip::Log::Level level,
|
||||
const resip::Subsystem& subsystem,
|
||||
const resip::Data& appName,
|
||||
const char* file,
|
||||
int line,
|
||||
const resip::Data& message,
|
||||
const resip::Data& messageWithHeaders,
|
||||
const resip::Data& instanceName) override;
|
||||
/** return true to also do default logging, false to suppress default logging. */
|
||||
virtual bool operator()(resip::Log::Level level,
|
||||
const resip::Subsystem& subsystem,
|
||||
const resip::Data& appName,
|
||||
const char* file,
|
||||
int line,
|
||||
const resip::Data& message,
|
||||
const resip::Data& messageWithHeaders,
|
||||
const resip::Data& instanceName) override;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region DnsResultSink implementation
|
||||
|
|
@ -402,92 +402,92 @@ public:
|
|||
#pragma endregion
|
||||
|
||||
#pragma region ClientPublicationHandler
|
||||
void onSuccess(resip::ClientPublicationHandle, const resip::SipMessage& status) override;
|
||||
void onRemove(resip::ClientPublicationHandle, const resip::SipMessage& status) override;
|
||||
void onFailure(resip::ClientPublicationHandle, const resip::SipMessage& status) override;
|
||||
int onRequestRetry(resip::ClientPublicationHandle, int retrySeconds, const resip::SipMessage& status) override;
|
||||
void onSuccess(resip::ClientPublicationHandle, const resip::SipMessage& status) override;
|
||||
void onRemove(resip::ClientPublicationHandle, const resip::SipMessage& status) override;
|
||||
void onFailure(resip::ClientPublicationHandle, const resip::SipMessage& status) override;
|
||||
int onRequestRetry(resip::ClientPublicationHandle, int retrySeconds, const resip::SipMessage& status) override;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region SubscriptionHandler
|
||||
void onUpdate(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify);
|
||||
void onUpdatePending(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override;
|
||||
void onUpdateActive(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override;
|
||||
|
||||
//unknown Subscription-State value
|
||||
void onUpdateExtension(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override;
|
||||
int onRequestRetry(resip::ClientSubscriptionHandle, int retrySeconds, const resip::SipMessage& notify) override;
|
||||
|
||||
//subscription can be ended through a notify or a failure response.
|
||||
void onTerminated(resip::ClientSubscriptionHandle, const resip::SipMessage* msg) override;
|
||||
//not sure if this has any value.
|
||||
void onNewSubscription(resip::ClientSubscriptionHandle, const resip::SipMessage& notify) override;
|
||||
void onUpdate(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify);
|
||||
void onUpdatePending(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override;
|
||||
void onUpdateActive(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override;
|
||||
|
||||
/// called to allow app to adorn a message.
|
||||
void onReadyToSend(resip::ClientSubscriptionHandle, resip::SipMessage& msg) override;
|
||||
void onNotifyNotReceived(resip::ClientSubscriptionHandle) override;
|
||||
//unknown Subscription-State value
|
||||
void onUpdateExtension(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder) override;
|
||||
int onRequestRetry(resip::ClientSubscriptionHandle, int retrySeconds, const resip::SipMessage& notify) override;
|
||||
|
||||
/// Called when a TCP or TLS flow to the server has terminated. This can be caused by socket
|
||||
/// errors, or missing CRLF keep alives pong responses from the server.
|
||||
// Called only if clientOutbound is enabled on the UserProfile and the first hop server
|
||||
/// supports RFC5626 (outbound).
|
||||
/// Default implementation is to re-form the subscription using a new flow
|
||||
void onFlowTerminated(resip::ClientSubscriptionHandle) override;
|
||||
void onNewSubscription(resip::ServerSubscriptionHandle, const resip::SipMessage& sub) override;
|
||||
void onTerminated(resip::ServerSubscriptionHandle) override;
|
||||
//subscription can be ended through a notify or a failure response.
|
||||
void onTerminated(resip::ClientSubscriptionHandle, const resip::SipMessage* msg) override;
|
||||
//not sure if this has any value.
|
||||
void onNewSubscription(resip::ClientSubscriptionHandle, const resip::SipMessage& notify) override;
|
||||
|
||||
/// called to allow app to adorn a message.
|
||||
void onReadyToSend(resip::ClientSubscriptionHandle, resip::SipMessage& msg) override;
|
||||
void onNotifyNotReceived(resip::ClientSubscriptionHandle) override;
|
||||
|
||||
/// Called when a TCP or TLS flow to the server has terminated. This can be caused by socket
|
||||
/// errors, or missing CRLF keep alives pong responses from the server.
|
||||
// Called only if clientOutbound is enabled on the UserProfile and the first hop server
|
||||
/// supports RFC5626 (outbound).
|
||||
/// Default implementation is to re-form the subscription using a new flow
|
||||
void onFlowTerminated(resip::ClientSubscriptionHandle) override;
|
||||
void onNewSubscription(resip::ServerSubscriptionHandle, const resip::SipMessage& sub) override;
|
||||
void onTerminated(resip::ServerSubscriptionHandle) override;
|
||||
#pragma endregion
|
||||
|
||||
#pragma region PagerHandler
|
||||
void onSuccess(resip::ClientPagerMessageHandle, const resip::SipMessage& status) override;
|
||||
void onFailure(resip::ClientPagerMessageHandle, const resip::SipMessage& status, std::unique_ptr<resip::Contents> contents) override;
|
||||
void onMessageArrived(resip::ServerPagerMessageHandle, const resip::SipMessage& message) override;
|
||||
void onSuccess(resip::ClientPagerMessageHandle, const resip::SipMessage& status) override;
|
||||
void onFailure(resip::ClientPagerMessageHandle, const resip::SipMessage& status, std::unique_ptr<resip::Contents> contents) override;
|
||||
void onMessageArrived(resip::ServerPagerMessageHandle, const resip::SipMessage& message) override;
|
||||
#pragma endregion
|
||||
|
||||
void onDumCanBeDeleted() override;
|
||||
void onDumCanBeDeleted() override;
|
||||
protected:
|
||||
// Mutex to protect this instance
|
||||
Mutex mGuard;
|
||||
// Mutex to protect this instance
|
||||
Mutex mGuard;
|
||||
|
||||
// Smart pointer to resiprocate's master profile instance. The stack configuration holds here.
|
||||
std::shared_ptr<resip::MasterProfile> mProfile;
|
||||
|
||||
// Resiprocate's SIP stack object pointer
|
||||
resip::SipStack* mStack;
|
||||
|
||||
// Resiprocate's dialog usage manager object pointer
|
||||
resip::DialogUsageManager* mDum;
|
||||
|
||||
// List of available transports. They are owned by SipStack - so there is no need to delete instances in UserAgent.
|
||||
std::vector<resip::InternalTransport*> mTransportList;
|
||||
// Smart pointer to resiprocate's master profile instance. The stack configuration holds here.
|
||||
std::shared_ptr<resip::MasterProfile> mProfile;
|
||||
|
||||
typedef std::map<int, PSession> SessionMap;
|
||||
|
||||
// Session's map
|
||||
SessionMap mSessionMap;
|
||||
// Resiprocate's SIP stack object pointer
|
||||
resip::SipStack* mStack;
|
||||
|
||||
// Used configuration
|
||||
VariantMap mConfig;
|
||||
// Resiprocate's dialog usage manager object pointer
|
||||
resip::DialogUsageManager* mDum;
|
||||
|
||||
// Action vector
|
||||
SIPActionVector mActionVector;
|
||||
|
||||
typedef std::map<int, PClientObserver> ClientObserverMap;
|
||||
ClientObserverMap mClientObserverMap;
|
||||
// List of available transports. They are owned by SipStack - so there is no need to delete instances in UserAgent.
|
||||
std::vector<resip::InternalTransport*> mTransportList;
|
||||
|
||||
typedef std::map<int, PServerObserver> ServerObserverMap;
|
||||
ServerObserverMap mServerObserverMap;
|
||||
|
||||
typedef std::set<PAccount> AccountSet;
|
||||
AccountSet mAccountSet;
|
||||
typedef std::map<int, PSession> SessionMap;
|
||||
|
||||
// Constructs and sends INVITE to remote peer. Remote peer address is stored inside session object.
|
||||
void sendOffer(Session* session);
|
||||
void internalStopSession(Session& session);
|
||||
void processWatchingList();
|
||||
bool handleMultipartRelatedNotify(const resip::SipMessage& notify);
|
||||
// Session's map
|
||||
SessionMap mSessionMap;
|
||||
|
||||
PSession getUserSession(int sessionId);
|
||||
PAccount getAccount(const resip::NameAddr& myAddr);
|
||||
PAccount getAccount(Account* account);
|
||||
PAccount getAccount(int sessionId);
|
||||
// Used configuration
|
||||
VariantMap mConfig;
|
||||
|
||||
// Action vector
|
||||
SIPActionVector mActionVector;
|
||||
|
||||
typedef std::map<int, PClientObserver> ClientObserverMap;
|
||||
ClientObserverMap mClientObserverMap;
|
||||
|
||||
typedef std::map<int, PServerObserver> ServerObserverMap;
|
||||
ServerObserverMap mServerObserverMap;
|
||||
|
||||
typedef std::set<PAccount> AccountSet;
|
||||
AccountSet mAccountSet;
|
||||
|
||||
// Constructs and sends INVITE to remote peer. Remote peer address is stored inside session object.
|
||||
void sendOffer(Session* session);
|
||||
void internalStopSession(Session& session);
|
||||
void processWatchingList();
|
||||
bool handleMultipartRelatedNotify(const resip::SipMessage& notify);
|
||||
|
||||
PSession getUserSession(int sessionId);
|
||||
PAccount getAccount(const resip::NameAddr& myAddr);
|
||||
PAccount getAccount(Account* account);
|
||||
PAccount getAccount(int sessionId);
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include "EP_Engine.h"
|
||||
|
||||
WatcherQueue::WatcherQueue(UserAgent& ua)
|
||||
:mActiveId(0), mAgent(ua)
|
||||
:mActiveId(0), mAgent(ua)
|
||||
{}
|
||||
|
||||
WatcherQueue::~WatcherQueue()
|
||||
|
|
@ -10,173 +10,173 @@ WatcherQueue::~WatcherQueue()
|
|||
|
||||
int WatcherQueue::add(std::string peer, std::string package, void* tag)
|
||||
{
|
||||
ice::Lock l(mGuard);
|
||||
ice::Lock l(mGuard);
|
||||
|
||||
// Check if queue has similar item
|
||||
for (unsigned i=0; i<mItemList.size(); i++)
|
||||
{
|
||||
Item& item = mItemList[i];
|
||||
if (item.mTarget == peer && item.mPackage == package &&
|
||||
item.mState != Item::State_Deleting)
|
||||
return item.mId;
|
||||
}
|
||||
// Check if queue has similar item
|
||||
for (unsigned i=0; i<mItemList.size(); i++)
|
||||
{
|
||||
Item& item = mItemList[i];
|
||||
if (item.mTarget == peer && item.mPackage == package &&
|
||||
item.mState != Item::State_Deleting)
|
||||
return item.mId;
|
||||
}
|
||||
|
||||
Item item;
|
||||
item.mTarget = peer;
|
||||
item.mPackage = package;
|
||||
item.mTag = tag;
|
||||
item.mState = Item::State_ScheduledToAdd;
|
||||
item.mSession = new ResipSession(*mAgent.mDum);
|
||||
item.mSession->setUa(&mAgent);
|
||||
item.mSession->setType(ResipSession::Type_Subscription);
|
||||
item.mSession->setTag(tag);
|
||||
item.mId = item.mSession->sessionId();
|
||||
item.mSession->setRemoteAddress(peer);
|
||||
item.mTag = tag;
|
||||
mItemList.push_back(item);
|
||||
process();
|
||||
Item item;
|
||||
item.mTarget = peer;
|
||||
item.mPackage = package;
|
||||
item.mTag = tag;
|
||||
item.mState = Item::State_ScheduledToAdd;
|
||||
item.mSession = new ResipSession(*mAgent.mDum);
|
||||
item.mSession->setUa(&mAgent);
|
||||
item.mSession->setType(ResipSession::Type_Subscription);
|
||||
item.mSession->setTag(tag);
|
||||
item.mId = item.mSession->sessionId();
|
||||
item.mSession->setRemoteAddress(peer);
|
||||
item.mTag = tag;
|
||||
mItemList.push_back(item);
|
||||
process();
|
||||
|
||||
return item.mId;
|
||||
return item.mId;
|
||||
}
|
||||
|
||||
void WatcherQueue::remove(int id)
|
||||
{
|
||||
ice::Lock l(mGuard);
|
||||
ice::Lock l(mGuard);
|
||||
|
||||
// Check if queue has similar item
|
||||
for (unsigned i=0; i<mItemList.size(); i++)
|
||||
{
|
||||
Item& item = mItemList[i];
|
||||
if (item.mId == id && !id)
|
||||
// Check if queue has similar item
|
||||
for (unsigned i=0; i<mItemList.size(); i++)
|
||||
{
|
||||
if (item.mState != Item::State_Deleting)
|
||||
item.mState = Item::State_ScheduledToDelete;
|
||||
Item& item = mItemList[i];
|
||||
if (item.mId == id && !id)
|
||||
{
|
||||
if (item.mState != Item::State_Deleting)
|
||||
item.mState = Item::State_ScheduledToDelete;
|
||||
}
|
||||
}
|
||||
}
|
||||
process();
|
||||
process();
|
||||
}
|
||||
|
||||
|
||||
void WatcherQueue::refresh(int id)
|
||||
{
|
||||
ice::Lock l(mGuard);
|
||||
ice::Lock l(mGuard);
|
||||
|
||||
// Check if queue has similar item
|
||||
for (unsigned i=0; i<mItemList.size(); i++)
|
||||
{
|
||||
Item& item = mItemList[i];
|
||||
if (item.mId == id && !id)
|
||||
// Check if queue has similar item
|
||||
for (unsigned i=0; i<mItemList.size(); i++)
|
||||
{
|
||||
if (item.mState == Item::State_ScheduledToDelete || item.mState == Item::State_Active)
|
||||
item.mState = Item::State_ScheduledToRefresh;
|
||||
Item& item = mItemList[i];
|
||||
if (item.mId == id && !id)
|
||||
{
|
||||
if (item.mState == Item::State_ScheduledToDelete || item.mState == Item::State_Active)
|
||||
item.mState = Item::State_ScheduledToRefresh;
|
||||
}
|
||||
}
|
||||
}
|
||||
process();
|
||||
process();
|
||||
}
|
||||
|
||||
void WatcherQueue::process()
|
||||
{
|
||||
while (!mActiveId)
|
||||
{
|
||||
// Find next item to process
|
||||
ItemList::iterator i = mItemList.begin();
|
||||
for (;i != mItemList.end() && !i->scheduled(); i++)
|
||||
;
|
||||
if (i == mItemList.end())
|
||||
return;
|
||||
|
||||
std::shared_ptr<resip::SipMessage> msg;
|
||||
int expires = DEFAULT_SUBSCRIPTION_TIME, refresh = DEFAULT_SUBSCRIPTION_REFRESHTIME;
|
||||
|
||||
switch (i->mState)
|
||||
while (!mActiveId)
|
||||
{
|
||||
case Item::State_ScheduledToAdd:
|
||||
if (mAgent.mConfig.exists(CONFIG_SUBSCRIPTION_TIME))
|
||||
expires = mAgent.mConfig[CONFIG_SUBSCRIPTION_TIME].asInt();
|
||||
if (mAgent.mConfig.exists(CONFIG_SUBSCRIPTION_REFRESHTIME))
|
||||
refresh = mAgent.mConfig[CONFIG_SUBSCRIPTION_REFRESHTIME].asInt();
|
||||
// Find next item to process
|
||||
ItemList::iterator i = mItemList.begin();
|
||||
for (;i != mItemList.end() && !i->scheduled(); i++)
|
||||
;
|
||||
if (i == mItemList.end())
|
||||
return;
|
||||
|
||||
msg = mAgent.mDum->makeSubscription(resip::NameAddr(resip::Data(i->mTarget)), resip::Data(i->mPackage),
|
||||
expires, refresh, i->mSession);
|
||||
msg->header(resip::h_Accepts) = mAgent.mDum->getMasterProfile()->getSupportedMimeTypes(resip::NOTIFY);
|
||||
mActiveId = i->mId;
|
||||
i->mState = Item::State_Adding;
|
||||
mAgent.mDum->send(msg);
|
||||
break;
|
||||
std::shared_ptr<resip::SipMessage> msg;
|
||||
int expires = DEFAULT_SUBSCRIPTION_TIME, refresh = DEFAULT_SUBSCRIPTION_REFRESHTIME;
|
||||
|
||||
case Item::State_ScheduledToDelete:
|
||||
i->mSession->runTerminatedEvent(ResipSession::Type_Subscription, 0, 0);
|
||||
if (i->mHandle.isValid())
|
||||
{
|
||||
mActiveId = i->mId;
|
||||
i->mHandle->end();
|
||||
i->mState = Item::State_Deleting;
|
||||
break;
|
||||
}
|
||||
else
|
||||
mItemList.erase(i);
|
||||
break;
|
||||
switch (i->mState)
|
||||
{
|
||||
case Item::State_ScheduledToAdd:
|
||||
if (mAgent.mConfig.exists(CONFIG_SUBSCRIPTION_TIME))
|
||||
expires = mAgent.mConfig[CONFIG_SUBSCRIPTION_TIME].asInt();
|
||||
if (mAgent.mConfig.exists(CONFIG_SUBSCRIPTION_REFRESHTIME))
|
||||
refresh = mAgent.mConfig[CONFIG_SUBSCRIPTION_REFRESHTIME].asInt();
|
||||
|
||||
case Item::State_ScheduledToRefresh:
|
||||
if (i->mHandle.isValid())
|
||||
{
|
||||
mActiveId = i->mId;
|
||||
i->mState = Item::State_Refreshing;
|
||||
i->mHandle->requestRefresh();
|
||||
}
|
||||
else
|
||||
mItemList.erase(i);
|
||||
break;
|
||||
msg = mAgent.mDum->makeSubscription(resip::NameAddr(resip::Data(i->mTarget)), resip::Data(i->mPackage),
|
||||
expires, refresh, i->mSession);
|
||||
msg->header(resip::h_Accepts) = mAgent.mDum->getMasterProfile()->getSupportedMimeTypes(resip::NOTIFY);
|
||||
mActiveId = i->mId;
|
||||
i->mState = Item::State_Adding;
|
||||
mAgent.mDum->send(msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case Item::State_ScheduledToDelete:
|
||||
i->mSession->runTerminatedEvent(ResipSession::Type_Subscription, 0, 0);
|
||||
if (i->mHandle.isValid())
|
||||
{
|
||||
mActiveId = i->mId;
|
||||
i->mHandle->end();
|
||||
i->mState = Item::State_Deleting;
|
||||
break;
|
||||
}
|
||||
else
|
||||
mItemList.erase(i);
|
||||
break;
|
||||
|
||||
case Item::State_ScheduledToRefresh:
|
||||
if (i->mHandle.isValid())
|
||||
{
|
||||
mActiveId = i->mId;
|
||||
i->mState = Item::State_Refreshing;
|
||||
i->mHandle->requestRefresh();
|
||||
}
|
||||
else
|
||||
mItemList.erase(i);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WatcherQueue::onTerminated(int id, int code)
|
||||
{
|
||||
ice::Lock l(mGuard);
|
||||
ItemList::iterator i = findById(id);
|
||||
if (i != mItemList.end())
|
||||
{
|
||||
if (i->mSession)
|
||||
i->mSession->runTerminatedEvent(ResipSession::Type_Subscription, code, 0);
|
||||
mItemList.erase(i);
|
||||
if (i->mId == mActiveId)
|
||||
mActiveId = 0;
|
||||
}
|
||||
process();
|
||||
ice::Lock l(mGuard);
|
||||
ItemList::iterator i = findById(id);
|
||||
if (i != mItemList.end())
|
||||
{
|
||||
if (i->mSession)
|
||||
i->mSession->runTerminatedEvent(ResipSession::Type_Subscription, code, 0);
|
||||
mItemList.erase(i);
|
||||
if (i->mId == mActiveId)
|
||||
mActiveId = 0;
|
||||
}
|
||||
process();
|
||||
}
|
||||
|
||||
void WatcherQueue::onEstablished(int id, int code)
|
||||
{
|
||||
ice::Lock l(mGuard);
|
||||
ItemList::iterator i = findById(id);
|
||||
if (i != mItemList.end())
|
||||
{
|
||||
i->mState = Item::State_Active;
|
||||
if (i->mId == mActiveId)
|
||||
mActiveId = 0;
|
||||
}
|
||||
process();
|
||||
ice::Lock l(mGuard);
|
||||
ItemList::iterator i = findById(id);
|
||||
if (i != mItemList.end())
|
||||
{
|
||||
i->mState = Item::State_Active;
|
||||
if (i->mId == mActiveId)
|
||||
mActiveId = 0;
|
||||
}
|
||||
process();
|
||||
}
|
||||
|
||||
WatcherQueue::ItemList::iterator WatcherQueue::findById(int id)
|
||||
{
|
||||
for (ItemList::iterator i=mItemList.begin(); i != mItemList.end(); i++)
|
||||
if (i->mId == id)
|
||||
return i;
|
||||
return mItemList.end();
|
||||
for (ItemList::iterator i=mItemList.begin(); i != mItemList.end(); i++)
|
||||
if (i->mId == id)
|
||||
return i;
|
||||
return mItemList.end();
|
||||
}
|
||||
|
||||
void WatcherQueue::clear()
|
||||
{
|
||||
ice::Lock l(mGuard);
|
||||
for (ItemList::iterator i=mItemList.begin(); i != mItemList.end(); i++)
|
||||
{
|
||||
if (i->mHandle.isValid())
|
||||
i->mHandle->end();
|
||||
}
|
||||
mItemList.clear();
|
||||
ice::Lock l(mGuard);
|
||||
for (ItemList::iterator i=mItemList.begin(); i != mItemList.end(); i++)
|
||||
{
|
||||
if (i->mHandle.isValid())
|
||||
i->mHandle->end();
|
||||
}
|
||||
mItemList.clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,57 +13,57 @@ class UserAgent;
|
|||
class WatcherQueue
|
||||
{
|
||||
public:
|
||||
struct Item
|
||||
{
|
||||
enum State
|
||||
struct Item
|
||||
{
|
||||
State_None,
|
||||
State_Active,
|
||||
State_ScheduledToAdd,
|
||||
State_Adding,
|
||||
State_ScheduledToRefresh,
|
||||
State_Refreshing,
|
||||
State_ScheduledToDelete,
|
||||
State_Deleting
|
||||
enum State
|
||||
{
|
||||
State_None,
|
||||
State_Active,
|
||||
State_ScheduledToAdd,
|
||||
State_Adding,
|
||||
State_ScheduledToRefresh,
|
||||
State_Refreshing,
|
||||
State_ScheduledToDelete,
|
||||
State_Deleting
|
||||
};
|
||||
|
||||
resip::ClientSubscriptionHandle mHandle; // Subscription handle
|
||||
ResipSession* mSession;
|
||||
State mState;
|
||||
std::string mTarget; // Target's address
|
||||
std::string mPackage; // Event package
|
||||
void* mTag; // User tag
|
||||
int mId;
|
||||
|
||||
Item()
|
||||
:mSession(NULL), mState(State_None), mTag(NULL), mId(0)
|
||||
{}
|
||||
|
||||
bool scheduled()
|
||||
{
|
||||
return mState == State_ScheduledToAdd || mState == State_ScheduledToDelete || mState == State_ScheduledToRefresh;
|
||||
}
|
||||
};
|
||||
WatcherQueue(UserAgent& agent);
|
||||
~WatcherQueue();
|
||||
|
||||
resip::ClientSubscriptionHandle mHandle; // Subscription handle
|
||||
ResipSession* mSession;
|
||||
State mState;
|
||||
std::string mTarget; // Target's address
|
||||
std::string mPackage; // Event package
|
||||
void* mTag; // User tag
|
||||
int mId;
|
||||
int add(std::string peer, std::string package, void* tag);
|
||||
void remove(int id);
|
||||
void refresh(int id);
|
||||
void clear();
|
||||
|
||||
Item()
|
||||
:mSession(NULL), mState(State_None), mTag(NULL), mId(0)
|
||||
{}
|
||||
|
||||
bool scheduled()
|
||||
{
|
||||
return mState == State_ScheduledToAdd || mState == State_ScheduledToDelete || mState == State_ScheduledToRefresh;
|
||||
}
|
||||
};
|
||||
WatcherQueue(UserAgent& agent);
|
||||
~WatcherQueue();
|
||||
|
||||
int add(std::string peer, std::string package, void* tag);
|
||||
void remove(int id);
|
||||
void refresh(int id);
|
||||
void clear();
|
||||
|
||||
void onTerminated(int id, int code);
|
||||
void onEstablished(int id, int code);
|
||||
void onTerminated(int id, int code);
|
||||
void onEstablished(int id, int code);
|
||||
|
||||
protected:
|
||||
typedef std::vector<Item> ItemList;
|
||||
ItemList mItemList;
|
||||
ice::Mutex mGuard;
|
||||
UserAgent& mAgent;
|
||||
int mActiveId;
|
||||
typedef std::vector<Item> ItemList;
|
||||
ItemList mItemList;
|
||||
ice::Mutex mGuard;
|
||||
UserAgent& mAgent;
|
||||
int mActiveId;
|
||||
|
||||
void process();
|
||||
ItemList::iterator findById(int id);
|
||||
void process();
|
||||
ItemList::iterator findById(int id);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,88 +19,88 @@ ClientObserver::~ClientObserver()
|
|||
|
||||
void ClientObserver::refresh()
|
||||
{
|
||||
if (mHandle.isValid())
|
||||
mHandle->requestRefresh();
|
||||
if (mHandle.isValid())
|
||||
mHandle->requestRefresh();
|
||||
}
|
||||
|
||||
void ClientObserver::stop()
|
||||
{
|
||||
if (mHandle.isValid())
|
||||
mHandle->end();
|
||||
else
|
||||
if (mSession)
|
||||
{
|
||||
mSession->runTerminatedEvent(ResipSession::Type_Subscription);
|
||||
if (mSession)
|
||||
mSession->end();
|
||||
}
|
||||
mSession = NULL;
|
||||
if (mHandle.isValid())
|
||||
mHandle->end();
|
||||
else
|
||||
if (mSession)
|
||||
{
|
||||
mSession->runTerminatedEvent(ResipSession::Type_Subscription);
|
||||
if (mSession)
|
||||
mSession->end();
|
||||
}
|
||||
mSession = NULL;
|
||||
}
|
||||
|
||||
std::string ClientObserver::peer()
|
||||
{
|
||||
return mPeer;
|
||||
return mPeer;
|
||||
}
|
||||
|
||||
ServerObserver::ServerObserver()
|
||||
:mState(State_Incoming)
|
||||
:mState(State_Incoming)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ServerObserver::~ServerObserver()
|
||||
{
|
||||
stop();
|
||||
stop();
|
||||
}
|
||||
|
||||
std::string ServerObserver::peer() const
|
||||
{
|
||||
return mPeer;
|
||||
return mPeer;
|
||||
}
|
||||
|
||||
std::string ServerObserver::package() const
|
||||
{
|
||||
return mPackage;
|
||||
return mPackage;
|
||||
}
|
||||
|
||||
void ServerObserver::update(std::string simpleId, bool online, std::string msg)
|
||||
{
|
||||
if (mState != State_Active)
|
||||
return;
|
||||
if (mState != State_Active)
|
||||
return;
|
||||
|
||||
resip::Pidf p;
|
||||
p.setEntity(mContact);
|
||||
p.setSimpleId(resip::Data(simpleId));
|
||||
p.setSimpleStatus(online, resip::Data(msg));
|
||||
resip::Pidf p;
|
||||
p.setEntity(mContact);
|
||||
p.setSimpleId(resip::Data(simpleId));
|
||||
p.setSimpleStatus(online, resip::Data(msg));
|
||||
|
||||
if (mHandle.isValid())
|
||||
mHandle->send(mHandle->update(&p));
|
||||
if (mHandle.isValid())
|
||||
mHandle->send(mHandle->update(&p));
|
||||
}
|
||||
|
||||
void ServerObserver::accept()
|
||||
{
|
||||
if (mHandle.isValid() && mState == State_Incoming)
|
||||
{
|
||||
mState = State_Active;
|
||||
mHandle->accept();
|
||||
}
|
||||
if (mHandle.isValid() && mState == State_Incoming)
|
||||
{
|
||||
mState = State_Active;
|
||||
mHandle->accept();
|
||||
}
|
||||
}
|
||||
|
||||
void ServerObserver::stop()
|
||||
{
|
||||
if (!mHandle.isValid())
|
||||
return;
|
||||
if (!mHandle.isValid())
|
||||
return;
|
||||
|
||||
switch (mState)
|
||||
{
|
||||
case State_Incoming:
|
||||
mHandle->reject(404);
|
||||
break;
|
||||
case State_Active:
|
||||
mHandle->end();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mState = State_Closed;
|
||||
switch (mState)
|
||||
{
|
||||
case State_Incoming:
|
||||
mHandle->reject(404);
|
||||
break;
|
||||
case State_Active:
|
||||
mHandle->end();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mState = State_Closed;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,51 +21,51 @@ class ResipSession;
|
|||
|
||||
class ClientObserver
|
||||
{
|
||||
friend class Account;
|
||||
friend class UserAgent;
|
||||
friend class Account;
|
||||
friend class UserAgent;
|
||||
public:
|
||||
ClientObserver();
|
||||
~ClientObserver();
|
||||
ClientObserver();
|
||||
~ClientObserver();
|
||||
|
||||
void refresh();
|
||||
void stop();
|
||||
std::string peer();
|
||||
void refresh();
|
||||
void stop();
|
||||
std::string peer();
|
||||
|
||||
protected:
|
||||
resip::ClientSubscriptionHandle mHandle;
|
||||
ResipSession* mSession;
|
||||
int mSessionId;
|
||||
std::string mPeer;
|
||||
resip::ClientSubscriptionHandle mHandle;
|
||||
ResipSession* mSession;
|
||||
int mSessionId;
|
||||
std::string mPeer;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<ClientObserver> PClientObserver;
|
||||
|
||||
class ServerObserver
|
||||
{
|
||||
friend class UserAgent;
|
||||
friend class UserAgent;
|
||||
public:
|
||||
ServerObserver();
|
||||
~ServerObserver();
|
||||
ServerObserver();
|
||||
~ServerObserver();
|
||||
|
||||
std::string peer() const;
|
||||
std::string package() const;
|
||||
std::string peer() const;
|
||||
std::string package() const;
|
||||
|
||||
void accept();
|
||||
void update(std::string simpleId, bool online, std::string msg);
|
||||
void stop();
|
||||
void accept();
|
||||
void update(std::string simpleId, bool online, std::string msg);
|
||||
void stop();
|
||||
|
||||
protected:
|
||||
enum State
|
||||
{
|
||||
State_Incoming,
|
||||
State_Active,
|
||||
State_Closed
|
||||
};
|
||||
State mState;
|
||||
resip::ServerSubscriptionHandle mHandle;
|
||||
std::string mPeer, mPackage;
|
||||
resip::Uri mContact;
|
||||
int mSessionId;
|
||||
enum State
|
||||
{
|
||||
State_Incoming,
|
||||
State_Active,
|
||||
State_Closed
|
||||
};
|
||||
State mState;
|
||||
resip::ServerSubscriptionHandle mHandle;
|
||||
std::string mPeer, mPackage;
|
||||
resip::Uri mContact;
|
||||
int mSessionId;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<ServerObserver> PServerObserver;
|
||||
|
|
|
|||
Loading…
Reference in New Issue