Use LinphoneEvent from the SUBSCRIBE to send all NOTIFY messages in the LocalConferenceEventHandler.

This commit is contained in:
Ghislain MARY 2017-11-09 11:39:45 +01:00
parent a77734766b
commit bb0b486a0e
4 changed files with 52 additions and 43 deletions

View file

@ -28,12 +28,14 @@
LINPHONE_BEGIN_NAMESPACE
class Participant;
class LocalConferenceEventHandlerPrivate : public ObjectPrivate {
public:
void notifyFullState (const std::string &notify, LinphoneEvent *lev);
void notifyAllExcept (const std::string &notify, const Address &addr);
void notifyFullState (const std::string &notify, const std::shared_ptr<Participant> &participant);
void notifyAllExcept (const std::string &notify, const std::shared_ptr<Participant> &exceptParticipant);
void notifyAll (const std::string &notify);
void notifyParticipant (const std::string &notify, const Address &addr);
void notifyParticipant (const std::string &notify, const std::shared_ptr<Participant> &participant);
std::string createNotifyFullState (int notifyId = -1);
std::string createNotifyParticipantAdded (const Address &addr, int notifyId = -1);
std::string createNotifyParticipantRemoved (const Address &addr, int notifyId = -1);
@ -50,7 +52,7 @@ private:
unsigned int lastNotify = 0;
std::string createNotify (Xsd::ConferenceInfo::ConferenceType confInfo, int notifyId = -1, bool isFullState = false);
void sendNotify (const std::string &notify, const Address &addr);
void sendNotify (const std::string &notify, const std::shared_ptr<Participant> &participant);
L_DECLARE_PUBLIC(LocalConferenceEventHandler);
};

View file

@ -37,39 +37,25 @@ using namespace Xsd::ConferenceInfo;
// -----------------------------------------------------------------------------
static void doNotify (const string &notify, LinphoneEvent *lev) {
LinphoneContent *content = linphone_core_create_content(lev->lc);
linphone_content_set_buffer(content, (const uint8_t *)notify.c_str(), strlen(notify.c_str()));
linphone_event_notify(lev, content);
linphone_content_unref(content);
void LocalConferenceEventHandlerPrivate::notifyFullState (const string &notify, const shared_ptr<Participant> &participant) {
sendNotify(notify, participant);
}
// -----------------------------------------------------------------------------
void LocalConferenceEventHandlerPrivate::notifyFullState (const string &notify, LinphoneEvent *lev) {
doNotify(notify, lev);
}
void LocalConferenceEventHandlerPrivate::notifyAllExcept (const string &notify, const Address &addr) {
SimpleAddress simpleAddr(addr);
void LocalConferenceEventHandlerPrivate::notifyAllExcept (const string &notify, const shared_ptr<Participant> &exceptParticipant) {
for (const auto &participant : conf->getParticipants()) {
if (participant->getPrivate()->isSubscribedToConferenceEventPackage() && (participant->getAddress() != simpleAddr))
sendNotify(notify, participant->getContactAddress());
if (participant->getPrivate()->isSubscribedToConferenceEventPackage() && (participant != exceptParticipant))
sendNotify(notify, participant);
}
}
void LocalConferenceEventHandlerPrivate::notifyAll (const string &notify) {
for (const auto &participant : conf->getParticipants()) {
if (participant->getPrivate()->isSubscribedToConferenceEventPackage())
sendNotify(notify, participant->getContactAddress());
}
for (const auto &participant : conf->getParticipants())
notifyParticipant(notify, participant);
}
void LocalConferenceEventHandlerPrivate::notifyParticipant (const string &notify, const Address &addr) {
SimpleAddress simpleAddr(addr);
shared_ptr<Participant> participant = conf->findParticipant(simpleAddr);
void LocalConferenceEventHandlerPrivate::notifyParticipant (const string &notify, const shared_ptr<Participant> &participant) {
if (participant->getPrivate()->isSubscribedToConferenceEventPackage())
sendNotify(notify, participant->getContactAddress());
sendNotify(notify, participant);
}
string LocalConferenceEventHandlerPrivate::createNotify (ConferenceType confInfo, int notifyId, bool isFullState) {
@ -249,13 +235,14 @@ string LocalConferenceEventHandlerPrivate::createNotifyParticipantDeviceRemoved
return createNotify(confInfo, notifyId);
}
void LocalConferenceEventHandlerPrivate::sendNotify (const string &notify, const Address &addr) {
LinphoneAddress *cAddr = linphone_address_new(addr.asString().c_str());
LinphoneEvent *lev = linphone_core_create_notify(core, cAddr, "conference");
// Fix the From header to put the chat room URI
lev->op->set_from(conf->getConferenceAddress().asString().c_str());
linphone_address_unref(cAddr);
doNotify(notify, lev);
void LocalConferenceEventHandlerPrivate::sendNotify (const string &notify, const shared_ptr<Participant> &participant) {
LinphoneEvent *ev = participant->getPrivate()->getConferenceSubscribeEvent();
if (!ev)
return;
LinphoneContent *content = linphone_core_create_content(ev->lc);
linphone_content_set_buffer(content, (const uint8_t *)notify.c_str(), strlen(notify.c_str()));
linphone_event_notify(ev, content);
linphone_content_unref(content);
}
// =============================================================================
@ -286,8 +273,8 @@ void LocalConferenceEventHandler::subscribeReceived (LinphoneEvent *lev) {
unsigned int lastNotify = static_cast<unsigned int>(Utils::stoi(linphone_event_get_custom_header(lev, "Last-Notify-Version")));
if (lastNotify == 0) {
lInfo() << "Sending initial notify of conference:" << d->conf->getConferenceAddress().asStringUriOnly() << " to: " << addrStr;
participant->getPrivate()->subscribeToConferenceEventPackage(true);
d->notifyFullState(d->createNotifyFullState(), lev);
participant->getPrivate()->setConferenceSubscribeEvent(lev);
d->notifyFullState(d->createNotifyFullState(), participant);
} else if (lastNotify < d->lastNotify) {
lInfo() << "Sending all missed notify for conference:" << d->conf->getConferenceAddress().asStringUriOnly() <<
" from: " << lastNotify << " to: " << addrStr;
@ -298,18 +285,20 @@ void LocalConferenceEventHandler::subscribeReceived (LinphoneEvent *lev) {
" should not be higher than last notify sent by server: [" << d->lastNotify << "].";
}
} else if (linphone_event_get_subscription_state(lev) == LinphoneSubscriptionTerminated)
participant->getPrivate()->subscribeToConferenceEventPackage(false);
participant->getPrivate()->setConferenceSubscribeEvent(nullptr);
}
}
void LocalConferenceEventHandler::notifyParticipantAdded (const Address &addr) {
L_D();
d->notifyAllExcept(d->createNotifyParticipantAdded(addr), addr);
shared_ptr<Participant> participant = d->conf->findParticipant(addr);
d->notifyAllExcept(d->createNotifyParticipantAdded(addr), participant);
}
void LocalConferenceEventHandler::notifyParticipantRemoved (const Address &addr) {
L_D();
d->notifyAllExcept(d->createNotifyParticipantRemoved(addr), addr);
shared_ptr<Participant> participant = d->conf->findParticipant(addr);
d->notifyAllExcept(d->createNotifyParticipantRemoved(addr), participant);
}
void LocalConferenceEventHandler::notifyParticipantSetAdmin (const Address &addr, bool isAdmin) {

View file

@ -37,12 +37,13 @@ LINPHONE_BEGIN_NAMESPACE
class ParticipantPrivate : public ObjectPrivate {
public:
virtual ~ParticipantPrivate () = default;
virtual ~ParticipantPrivate ();
std::shared_ptr<CallSession> createSession (const Conference &conference, const CallSessionParams *params, bool hasMedia, CallSessionListener *listener);
inline std::shared_ptr<CallSession> getSession () const { return session; }
inline bool isSubscribedToConferenceEventPackage () const { return _isSubscribedToConferenceEventPackage; }
inline void subscribeToConferenceEventPackage (bool value) { _isSubscribedToConferenceEventPackage = value; }
inline bool isSubscribedToConferenceEventPackage () const { return conferenceSubscribeEvent != nullptr; }
LinphoneEvent *getConferenceSubscribeEvent () const { return conferenceSubscribeEvent; }
void setConferenceSubscribeEvent (LinphoneEvent *ev);
inline void removeSession () { session.reset(); }
inline void setAddress (const SimpleAddress &newAddr) { addr = newAddr; }
inline void setAdmin (bool isAdmin) { this->isAdmin = isAdmin; }
@ -56,7 +57,7 @@ private:
SimpleAddress addr;
Address contactAddr;
bool isAdmin = false;
bool _isSubscribedToConferenceEventPackage = false;
LinphoneEvent *conferenceSubscribeEvent = nullptr;
std::shared_ptr<CallSession> session;
std::list<ParticipantDevice> devices;

View file

@ -26,12 +26,21 @@
#include "params/media-session-params.h"
#include "session/media-session.h"
#include "linphone/event.h"
using namespace std;
LINPHONE_BEGIN_NAMESPACE
// =============================================================================
ParticipantPrivate::~ParticipantPrivate () {
if (conferenceSubscribeEvent)
linphone_event_unref(conferenceSubscribeEvent);
}
// -----------------------------------------------------------------------------
shared_ptr<CallSession> ParticipantPrivate::createSession (
const Conference &conference, const CallSessionParams *params, bool hasMedia, CallSessionListener *listener
) {
@ -45,6 +54,14 @@ shared_ptr<CallSession> ParticipantPrivate::createSession (
// -----------------------------------------------------------------------------
void ParticipantPrivate::setConferenceSubscribeEvent (LinphoneEvent *ev) {
if (conferenceSubscribeEvent)
linphone_event_unref(conferenceSubscribeEvent);
conferenceSubscribeEvent = linphone_event_ref(ev);
}
// -----------------------------------------------------------------------------
const list<ParticipantDevice>::const_iterator ParticipantPrivate::findDevice (const Address &gruu) const {
ParticipantDevice device(gruu);
return find(devices.cbegin(), devices.cend(), device);