diff --git a/src/conference/local-conference-event-handler-p.h b/src/conference/local-conference-event-handler-p.h index 55fefde4e..53c2761eb 100644 --- a/src/conference/local-conference-event-handler-p.h +++ b/src/conference/local-conference-event-handler-p.h @@ -35,7 +35,6 @@ public: 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 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); @@ -52,7 +51,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 std::shared_ptr &participant); + void notifyParticipant (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 f5d07ec37..27a57a1ef 100644 --- a/src/conference/local-conference-event-handler.cpp +++ b/src/conference/local-conference-event-handler.cpp @@ -38,13 +38,13 @@ using namespace Xsd::ConferenceInfo; // ----------------------------------------------------------------------------- void LocalConferenceEventHandlerPrivate::notifyFullState (const string ¬ify, const shared_ptr &participant) { - sendNotify(notify, participant); + notifyParticipant(notify, participant); } void LocalConferenceEventHandlerPrivate::notifyAllExcept (const string ¬ify, const shared_ptr &exceptParticipant) { for (const auto &participant : conf->getParticipants()) { - if (participant->getPrivate()->isSubscribedToConferenceEventPackage() && (participant != exceptParticipant)) - sendNotify(notify, participant); + if (participant != exceptParticipant) + notifyParticipant(notify, participant); } } @@ -54,8 +54,15 @@ void LocalConferenceEventHandlerPrivate::notifyAll (const string ¬ify) { } void LocalConferenceEventHandlerPrivate::notifyParticipant (const string ¬ify, const shared_ptr &participant) { - if (participant->getPrivate()->isSubscribedToConferenceEventPackage()) - sendNotify(notify, participant); + for (const auto &device : participant->getPrivate()->getDevices()) { + if (device->isSubscribedToConferenceEventPackage()) { + LinphoneEvent *ev = device->getConferenceSubscribeEvent(); + 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); + } + } } string LocalConferenceEventHandlerPrivate::createNotify (ConferenceType confInfo, int notifyId, bool isFullState) { @@ -235,16 +242,6 @@ string LocalConferenceEventHandlerPrivate::createNotifyParticipantDeviceRemoved return createNotify(confInfo, notifyId); } -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); -} - // ============================================================================= LocalConferenceEventHandler::LocalConferenceEventHandler (LinphoneCore *core, LocalConference *localConf) : @@ -268,25 +265,35 @@ void LocalConferenceEventHandler::subscribeReceived (LinphoneEvent *lev) { char *addrStr = linphone_address_as_string(lAddr); shared_ptr participant = d->conf->findParticipant(Address(addrStr)); bctbx_free(addrStr); - if (participant) { - if (linphone_event_get_subscription_state(lev) == LinphoneSubscriptionActive) { - 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()->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; - // TODO : send all missed notify from lastNotify to d->lastNotify - } else if (lastNotify > d->lastNotify) { - lError() << "last notify received by client: [" << lastNotify <<"] for confernce:" << - d->conf->getConferenceAddress().asStringUriOnly() << - " should not be higher than last notify sent by server: [" << d->lastNotify << "]."; - } - } else if (linphone_event_get_subscription_state(lev) == LinphoneSubscriptionTerminated) - participant->getPrivate()->setConferenceSubscribeEvent(nullptr); - } + if (!participant) + return; + + const LinphoneAddress *lContactAddr = linphone_event_get_remote_contact(lev); + char *contactAddrStr = linphone_address_as_string(lContactAddr); + Address contactAddr(contactAddrStr); + bctbx_free(contactAddrStr); + if (contactAddr.getUriParamValue("gr").empty()) + return; + GruuAddress gruu(contactAddr); + shared_ptr device = participant->getPrivate()->addDevice(gruu); + + if (linphone_event_get_subscription_state(lev) == LinphoneSubscriptionActive) { + 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: " << participant->getAddress().asString(); + device->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: " << participant->getAddress().asString(); + // TODO : send all missed notify from lastNotify to d->lastNotify + } else if (lastNotify > d->lastNotify) { + lError() << "last notify received by client: [" << lastNotify <<"] for conference:" << + d->conf->getConferenceAddress().asStringUriOnly() << + " should not be higher than last notify sent by server: [" << d->lastNotify << "]"; + } + } else if (linphone_event_get_subscription_state(lev) == LinphoneSubscriptionTerminated) + device->setConferenceSubscribeEvent(nullptr); } void LocalConferenceEventHandler::notifyParticipantAdded (const Address &addr) { diff --git a/src/conference/participant-device.cpp b/src/conference/participant-device.cpp index e7d60f385..7aefa714d 100644 --- a/src/conference/participant-device.cpp +++ b/src/conference/participant-device.cpp @@ -19,6 +19,8 @@ #include "participant-device.h" +#include "linphone/event.h" + using namespace std; // ============================================================================= @@ -31,8 +33,19 @@ ParticipantDevice::ParticipantDevice (const GruuAddress &gruu) { mGruu = gruu; } +ParticipantDevice::~ParticipantDevice () { + if (mConferenceSubscribeEvent) + linphone_event_unref(mConferenceSubscribeEvent); +} + bool ParticipantDevice::operator== (const ParticipantDevice &device) const { return (mGruu == device.getGruu()); } +void ParticipantDevice::setConferenceSubscribeEvent (LinphoneEvent *ev) { + if (mConferenceSubscribeEvent) + linphone_event_unref(mConferenceSubscribeEvent); + mConferenceSubscribeEvent = linphone_event_ref(ev); +} + LINPHONE_END_NAMESPACE diff --git a/src/conference/participant-device.h b/src/conference/participant-device.h index d889d9e22..890f8246e 100644 --- a/src/conference/participant-device.h +++ b/src/conference/participant-device.h @@ -24,6 +24,7 @@ #include #include "address/gruu-address.h" +#include "linphone/types.h" #include "linphone/utils/general.h" // ============================================================================= @@ -36,6 +37,7 @@ class ParticipantDevice { public: ParticipantDevice (); explicit ParticipantDevice (const GruuAddress &gruu); + virtual ~ParticipantDevice (); bool operator== (const ParticipantDevice &device) const; @@ -43,11 +45,16 @@ public: inline std::shared_ptr getSession () const { return mSession; } inline void setSession (std::shared_ptr session) { mSession = session; } + inline bool isSubscribedToConferenceEventPackage () const { return mConferenceSubscribeEvent != nullptr; } + LinphoneEvent *getConferenceSubscribeEvent () const { return mConferenceSubscribeEvent; } + void setConferenceSubscribeEvent (LinphoneEvent *ev); + bool isValid () const { return mGruu.isValid(); } private: GruuAddress mGruu; std::shared_ptr mSession; + LinphoneEvent *mConferenceSubscribeEvent = nullptr; }; LINPHONE_END_NAMESPACE diff --git a/src/conference/participant-p.h b/src/conference/participant-p.h index 7327ee9d2..2db34d89e 100644 --- a/src/conference/participant-p.h +++ b/src/conference/participant-p.h @@ -29,21 +29,14 @@ #include "conference/session/call-session-listener.h" #include "conference/params/call-session-params.h" -#include "linphone/types.h" - // ============================================================================= LINPHONE_BEGIN_NAMESPACE class ParticipantPrivate : public ObjectPrivate { public: - 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 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; } @@ -58,7 +51,6 @@ private: SimpleAddress addr; Address contactAddr; bool isAdmin = false; - LinphoneEvent *conferenceSubscribeEvent = nullptr; std::shared_ptr session; std::list> devices; diff --git a/src/conference/participant.cpp b/src/conference/participant.cpp index d8d1b89be..d8be578b4 100644 --- a/src/conference/participant.cpp +++ b/src/conference/participant.cpp @@ -26,21 +26,12 @@ #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 ) { @@ -54,14 +45,6 @@ shared_ptr ParticipantPrivate::createSession ( // ----------------------------------------------------------------------------- -void ParticipantPrivate::setConferenceSubscribeEvent (LinphoneEvent *ev) { - if (conferenceSubscribeEvent) - linphone_event_unref(conferenceSubscribeEvent); - conferenceSubscribeEvent = linphone_event_ref(ev); -} - -// ----------------------------------------------------------------------------- - shared_ptr ParticipantPrivate::findDevice (const GruuAddress &gruu) const { for (const auto &device : devices) { if (device->getGruu() == gruu) @@ -83,12 +66,12 @@ const list> &ParticipantPrivate::getDevices () con } shared_ptr ParticipantPrivate::addDevice (const GruuAddress &gruu) { - if (!findDevice(gruu)) { - shared_ptr device = make_shared(gruu); - devices.push_back(device); + shared_ptr device = findDevice(gruu); + if (device) return device; - } - return nullptr; + device = make_shared(gruu); + devices.push_back(device); + return device; } void ParticipantPrivate::removeDevice (const GruuAddress &gruu) {