diff --git a/src/conference/local-conference-event-handler-p.h b/src/conference/local-conference-event-handler-p.h index 88e26d437..55fefde4e 100644 --- a/src/conference/local-conference-event-handler-p.h +++ b/src/conference/local-conference-event-handler-p.h @@ -28,12 +28,14 @@ LINPHONE_BEGIN_NAMESPACE +class Participant; + class LocalConferenceEventHandlerPrivate : public ObjectPrivate { public: - void notifyFullState (const std::string ¬ify, LinphoneEvent *lev); - void notifyAllExcept (const std::string ¬ify, const Address &addr); + void notifyFullState (const std::string ¬ify, const std::shared_ptr &participant); + void notifyAllExcept (const std::string ¬ify, const std::shared_ptr &exceptParticipant); void notifyAll (const std::string ¬ify); - void notifyParticipant (const std::string ¬ify, const Address &addr); + void notifyParticipant (const std::string ¬ify, const std::shared_ptr &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 ¬ify, const Address &addr); + void sendNotify (const std::string ¬ify, const std::shared_ptr &participant); L_DECLARE_PUBLIC(LocalConferenceEventHandler); }; diff --git a/src/conference/local-conference-event-handler.cpp b/src/conference/local-conference-event-handler.cpp index 518dd4abe..93e970114 100644 --- a/src/conference/local-conference-event-handler.cpp +++ b/src/conference/local-conference-event-handler.cpp @@ -37,39 +37,25 @@ using namespace Xsd::ConferenceInfo; // ----------------------------------------------------------------------------- -static void doNotify (const string ¬ify, 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 ¬ify, const shared_ptr &participant) { + sendNotify(notify, participant); } -// ----------------------------------------------------------------------------- - -void LocalConferenceEventHandlerPrivate::notifyFullState (const string ¬ify, LinphoneEvent *lev) { - doNotify(notify, lev); -} - -void LocalConferenceEventHandlerPrivate::notifyAllExcept (const string ¬ify, const Address &addr) { - SimpleAddress simpleAddr(addr); +void LocalConferenceEventHandlerPrivate::notifyAllExcept (const string ¬ify, const shared_ptr &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 ¬ify) { - 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 ¬ify, const Address &addr) { - SimpleAddress simpleAddr(addr); - shared_ptr participant = conf->findParticipant(simpleAddr); +void LocalConferenceEventHandlerPrivate::notifyParticipant (const string ¬ify, const shared_ptr &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 ¬ify, 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 ¬ify, const shared_ptr &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(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 = 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 = d->conf->findParticipant(addr); + d->notifyAllExcept(d->createNotifyParticipantRemoved(addr), participant); } void LocalConferenceEventHandler::notifyParticipantSetAdmin (const Address &addr, bool isAdmin) { diff --git a/src/conference/participant-p.h b/src/conference/participant-p.h index 58993cd97..a412d4cb7 100644 --- a/src/conference/participant-p.h +++ b/src/conference/participant-p.h @@ -37,12 +37,13 @@ LINPHONE_BEGIN_NAMESPACE class ParticipantPrivate : public ObjectPrivate { public: - virtual ~ParticipantPrivate () = default; + virtual ~ParticipantPrivate (); std::shared_ptr createSession (const Conference &conference, const CallSessionParams *params, bool hasMedia, CallSessionListener *listener); inline std::shared_ptr 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 session; std::list devices; diff --git a/src/conference/participant.cpp b/src/conference/participant.cpp index cf2e370b4..289b483d0 100644 --- a/src/conference/participant.cpp +++ b/src/conference/participant.cpp @@ -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 ParticipantPrivate::createSession ( const Conference &conference, const CallSessionParams *params, bool hasMedia, CallSessionListener *listener ) { @@ -45,6 +54,14 @@ shared_ptr ParticipantPrivate::createSession ( // ----------------------------------------------------------------------------- +void ParticipantPrivate::setConferenceSubscribeEvent (LinphoneEvent *ev) { + if (conferenceSubscribeEvent) + linphone_event_unref(conferenceSubscribeEvent); + conferenceSubscribeEvent = linphone_event_ref(ev); +} + +// ----------------------------------------------------------------------------- + const list::const_iterator ParticipantPrivate::findDevice (const Address &gruu) const { ParticipantDevice device(gruu); return find(devices.cbegin(), devices.cend(), device);