From 532020bb4c64f24d6055f91e58998819e5d2fc10 Mon Sep 17 00:00:00 2001 From: Benjamin Reis Date: Wed, 11 Oct 2017 11:26:59 +0200 Subject: [PATCH] handle add/remove of participant's device in conference event handlers --- src/chat/client-group-chat-room.cpp | 6 +- .../local-conference-event-handler-p.h | 3 + .../local-conference-event-handler.cpp | 99 ++++++++++++++++--- .../local-conference-event-handler.h | 6 +- .../remote-conference-event-handler.cpp | 27 +++-- .../remote-conference-event-handler.h | 12 +-- 6 files changed, 119 insertions(+), 34 deletions(-) diff --git a/src/chat/client-group-chat-room.cpp b/src/chat/client-group-chat-room.cpp index 907c93d74..ce02a4563 100644 --- a/src/chat/client-group-chat-room.cpp +++ b/src/chat/client-group-chat-room.cpp @@ -243,7 +243,7 @@ void ClientGroupChatRoom::onParticipantRemoved (const Address &addr) { } void ClientGroupChatRoom::onParticipantSetAdmin (const Address &addr, bool isAdmin) { - shared_ptr participant = nullptr; + shared_ptr participant; if (isMe(addr)) participant = me; else @@ -270,7 +270,7 @@ void ClientGroupChatRoom::onSubjectChanged (const std::string &subject) { } void ClientGroupChatRoom::onParticipantDeviceAdded (const Address &addr, const Address &gruu) { - shared_ptr participant = nullptr; + shared_ptr participant; if (isMe(addr)) participant = me; else @@ -283,7 +283,7 @@ void ClientGroupChatRoom::onParticipantDeviceAdded (const Address &addr, const A } void ClientGroupChatRoom::onParticipantDeviceRemoved (const Address &addr, const Address &gruu) { - shared_ptr participant = nullptr; + shared_ptr participant; if (isMe(addr)) participant = me; else diff --git a/src/conference/local-conference-event-handler-p.h b/src/conference/local-conference-event-handler-p.h index 264175c70..b50af3ed7 100644 --- a/src/conference/local-conference-event-handler-p.h +++ b/src/conference/local-conference-event-handler-p.h @@ -37,12 +37,15 @@ public: std::string createNotifyParticipantRemoved (const Address &addr); std::string createNotifyParticipantAdmined (const Address &addr, bool isAdmin); std::string createNotifySubjectChanged (); + std::string createNotifyParticipantDeviceAdded (const Address &addr, const Address &gruu); + std::string createNotifyParticipantDeviceRemoved (const Address &addr, const Address &gruu); private: LinphoneCore *core = nullptr; LocalConference *conf = nullptr; void sendNotify (const std::string ¬ify, const Address &addr); + L_DECLARE_PUBLIC(LocalConferenceEventHandler); }; diff --git a/src/conference/local-conference-event-handler.cpp b/src/conference/local-conference-event-handler.cpp index 1476728ab..d58835022 100644 --- a/src/conference/local-conference-event-handler.cpp +++ b/src/conference/local-conference-event-handler.cpp @@ -64,7 +64,7 @@ void LocalConferenceEventHandlerPrivate::notifyAllExcept (const string ¬ify, for (const auto &participant : conf->getParticipants()) { Address cleanedParticipantAddr(participant->getAddress()); cleanedParticipantAddr.setPort(0); - if (participant->getPrivate()->isSubscribedToConferenceEventPackage() && !(cleanedAddr.weakEqual(cleanedParticipantAddr))) + if (participant->getPrivate()->isSubscribedToConferenceEventPackage() && !cleanedAddr.weakEqual(cleanedParticipantAddr)) sendNotify(notify, participant->getAddress()); } } @@ -77,8 +77,8 @@ void LocalConferenceEventHandlerPrivate::notifyAll (const string ¬ify) { } string LocalConferenceEventHandlerPrivate::createNotifyFullState () { - string entity = this->conf->getConferenceAddress()->asStringUriOnly(); - string subject = this->conf->getSubject(); + string entity = conf->getConferenceAddress()->asStringUriOnly(); + string subject = conf->getSubject(); ConferenceType confInfo = ConferenceType(entity); UsersType users; ConferenceDescriptionType confDescr = ConferenceDescriptionType(); @@ -86,38 +86,51 @@ string LocalConferenceEventHandlerPrivate::createNotifyFullState () { confInfo.setUsers(users); confInfo.setConferenceDescription((const ConferenceDescriptionType) confDescr); - for (const auto &participant : this->conf->getParticipants()) { + for (const auto &participant : conf->getParticipants()) { UserType user = UserType(); UserRolesType roles; + UserType::EndpointSequence endpoints; user.setRoles(roles); + user.setEndpoint(endpoints); user.setEntity(participant->getAddress().asStringUriOnly()); user.getRoles()->getEntry().push_back(participant->isAdmin() ? "admin" : "participant"); user.setState("full"); + + for (const auto &device : participant->getPrivate()->getDevices()) { + const string &gruu = device.getGruu().asStringUriOnly(); + EndpointType endpoint = EndpointType(); + endpoint.setEntity(gruu); + endpoint.setState("full"); + user.getEndpoint().push_back(endpoint); + } + confInfo.getUsers()->getUser().push_back(user); } - return(createNotify(confInfo)); + return createNotify(confInfo); } string LocalConferenceEventHandlerPrivate::createNotifyParticipantAdded (const Address &addr) { - string entity = this->conf->getConferenceAddress()->asStringUriOnly(); + string entity = conf->getConferenceAddress()->asStringUriOnly(); ConferenceType confInfo = ConferenceType(entity); UsersType users; confInfo.setUsers(users); UserType user = UserType(); UserRolesType roles; + UserType::EndpointSequence endpoints; user.setRoles(roles); user.setEntity(addr.asStringUriOnly()); user.getRoles()->getEntry().push_back("participant"); user.setState("full"); + confInfo.getUsers()->getUser().push_back(user); - return(createNotify(confInfo)); + return createNotify(confInfo); } string LocalConferenceEventHandlerPrivate::createNotifyParticipantRemoved (const Address &addr) { - string entity = this->conf->getConferenceAddress()->asStringUriOnly(); + string entity = conf->getConferenceAddress()->asStringUriOnly(); ConferenceType confInfo = ConferenceType(entity); UsersType users; confInfo.setUsers(users); @@ -127,11 +140,11 @@ string LocalConferenceEventHandlerPrivate::createNotifyParticipantRemoved (const user.setState("deleted"); confInfo.getUsers()->getUser().push_back(user); - return(createNotify(confInfo)); + return createNotify(confInfo); } string LocalConferenceEventHandlerPrivate::createNotifyParticipantAdmined (const Address &addr, bool isAdmin) { - string entity = this->conf->getConferenceAddress()->asStringUriOnly(); + string entity = conf->getConferenceAddress()->asStringUriOnly(); ConferenceType confInfo = ConferenceType(entity); UsersType users; confInfo.setUsers(users); @@ -144,25 +157,71 @@ string LocalConferenceEventHandlerPrivate::createNotifyParticipantAdmined (const user.setState("partial"); confInfo.getUsers()->getUser().push_back(user); - return(createNotify(confInfo)); + return createNotify(confInfo); } string LocalConferenceEventHandlerPrivate::createNotifySubjectChanged () { - string entity = this->conf->getConferenceAddress()->asStringUriOnly(); - string subject = this->conf->getSubject(); + string entity = conf->getConferenceAddress()->asStringUriOnly(); + string subject = conf->getSubject(); ConferenceType confInfo = ConferenceType(entity); ConferenceDescriptionType confDescr = ConferenceDescriptionType(); confDescr.setSubject(subject); confInfo.setConferenceDescription((const ConferenceDescriptionType)confDescr); - return(createNotify(confInfo)); + return createNotify(confInfo); +} + +string LocalConferenceEventHandlerPrivate::createNotifyParticipantDeviceAdded (const Address &addr, const Address &gruu) { + string entity = conf->getConferenceAddress()->asStringUriOnly(); + string subject = conf->getSubject(); + ConferenceType confInfo = ConferenceType(entity); + + UserType user = UserType(); + UserRolesType roles; + UserType::EndpointSequence endpoints; + user.setRoles(roles); + user.setEntity(addr.asStringUriOnly()); + user.getRoles()->getEntry().push_back("participant"); + user.setState("partial"); + + EndpointType endpoint = EndpointType(); + endpoint.setEntity(gruu.asStringUriOnly()); + endpoint.setState("full"); + user.getEndpoint().push_back(endpoint); + + confInfo.getUsers()->getUser().push_back(user); + + return createNotify(confInfo); +} + +string LocalConferenceEventHandlerPrivate::createNotifyParticipantDeviceRemoved (const Address &addr, const Address &gruu) { + string entity = conf->getConferenceAddress()->asStringUriOnly(); + string subject = conf->getSubject(); + ConferenceType confInfo = ConferenceType(entity); + + UserType user = UserType(); + UserRolesType roles; + UserType::EndpointSequence endpoints; + user.setRoles(roles); + user.setEntity(addr.asStringUriOnly()); + user.getRoles()->getEntry().push_back("participant"); + user.setState("partial"); + + EndpointType endpoint = EndpointType(); + endpoint.setEntity(gruu.asStringUriOnly()); + endpoint.setState("deleted"); + user.getEndpoint().push_back(endpoint); + + confInfo.getUsers()->getUser().push_back(user); + + return createNotify(confInfo); } 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(this->conf->getConferenceAddress()->asString().c_str()); + lev->op->set_from(conf->getConferenceAddress()->asString().c_str()); linphone_address_unref(cAddr); doNotify(notify, lev); } @@ -217,4 +276,14 @@ void LocalConferenceEventHandler::notifySubjectChanged () { d->notifyAll(d->createNotifySubjectChanged()); } +void LocalConferenceEventHandler::notifyParticipantDeviceAdded (const Address &addr, const Address &gruu) { + L_D(); + d->notifyAll(d->createNotifyParticipantDeviceAdded(addr, gruu)); +} + +void LocalConferenceEventHandler::notifyParticipantDeviceRemoved (const Address &addr, const Address &gruu) { + L_D(); + d->notifyAll(d->createNotifyParticipantDeviceRemoved(addr, gruu)); +} + LINPHONE_END_NAMESPACE diff --git a/src/conference/local-conference-event-handler.h b/src/conference/local-conference-event-handler.h index 5568ed171..f34eaee7d 100644 --- a/src/conference/local-conference-event-handler.h +++ b/src/conference/local-conference-event-handler.h @@ -31,14 +31,16 @@ class LocalConferenceEventHandlerPrivate; class LocalConferenceEventHandler : public Object { public: - LocalConferenceEventHandler(LinphoneCore *core, LocalConference *localConf); - ~LocalConferenceEventHandler(); + LocalConferenceEventHandler (LinphoneCore *core, LocalConference *localConf); + ~LocalConferenceEventHandler (); void subscribeReceived (LinphoneEvent *lev); void notifyParticipantAdded (const Address &addr); void notifyParticipantRemoved (const Address &addr); void notifyParticipantSetAdmin (const Address &addr, bool isAdmin); void notifySubjectChanged (); + void notifyParticipantDeviceAdded (const Address &addr, const Address &gruu); + void notifyParticipantDeviceRemoved (const Address &addr, const Address &gruu); private: L_DECLARE_PRIVATE(LocalConferenceEventHandler); diff --git a/src/conference/remote-conference-event-handler.cpp b/src/conference/remote-conference-event-handler.cpp index 216e8e568..163f9961a 100644 --- a/src/conference/remote-conference-event-handler.cpp +++ b/src/conference/remote-conference-event-handler.cpp @@ -32,7 +32,7 @@ using namespace Xsd::ConferenceInfo; // ----------------------------------------------------------------------------- -RemoteConferenceEventHandler::RemoteConferenceEventHandler(LinphoneCore *core, ConferenceListener *listener) +RemoteConferenceEventHandler::RemoteConferenceEventHandler (LinphoneCore *core, ConferenceListener *listener) : Object(*new RemoteConferenceEventHandlerPrivate) { L_D(); xercesc::XMLPlatformUtils::Initialize(); @@ -40,13 +40,13 @@ RemoteConferenceEventHandler::RemoteConferenceEventHandler(LinphoneCore *core, C d->listener = listener; } -RemoteConferenceEventHandler::~RemoteConferenceEventHandler() { +RemoteConferenceEventHandler::~RemoteConferenceEventHandler () { xercesc::XMLPlatformUtils::Terminate(); } // ----------------------------------------------------------------------------- -void RemoteConferenceEventHandler::subscribe(const Address &addr) { +void RemoteConferenceEventHandler::subscribe (const Address &addr) { L_D(); d->confAddress = addr; LinphoneAddress *lAddr = linphone_address_new(d->confAddress.asString().c_str()); @@ -57,7 +57,7 @@ void RemoteConferenceEventHandler::subscribe(const Address &addr) { linphone_event_send_subscribe(d->lev, nullptr); } -void RemoteConferenceEventHandler::unsubscribe() { +void RemoteConferenceEventHandler::unsubscribe () { L_D(); if (d->lev) { linphone_event_terminate(d->lev); @@ -65,7 +65,7 @@ void RemoteConferenceEventHandler::unsubscribe() { } } -void RemoteConferenceEventHandler::notifyReceived(string xmlBody) { +void RemoteConferenceEventHandler::notifyReceived (string xmlBody) { L_D(); lInfo() << "NOTIFY received for conference " << d->confAddress.asString(); istringstream data(xmlBody); @@ -73,10 +73,10 @@ void RemoteConferenceEventHandler::notifyReceived(string xmlBody) { Address cleanedConfAddress = d->confAddress; cleanedConfAddress.setPort(0); if (confInfo->getEntity() == cleanedConfAddress.asString()) { - if(confInfo->getConferenceDescription().present() && confInfo->getConferenceDescription().get().getSubject().present()) + if (confInfo->getConferenceDescription().present() && confInfo->getConferenceDescription().get().getSubject().present()) d->listener->onSubjectChanged(confInfo->getConferenceDescription().get().getSubject().get()); - if(!confInfo->getUsers().present()) + if (!confInfo->getUsers().present()) return; for (const auto &user : confInfo->getUsers()->getUser()) { @@ -99,6 +99,17 @@ void RemoteConferenceEventHandler::notifyReceived(string xmlBody) { if (user.getState() == "full") d->listener->onParticipantAdded(addr); d->listener->onParticipantSetAdmin(addr, isAdmin); + for (const auto &endpoint : user.getEndpoint()) { + if (!endpoint.getEntity().present()) + break; + + Address gruu(endpoint.getEntity().get()); + if (endpoint.getState() == "deleted") + d->listener->onParticipantDeviceRemoved(addr, gruu); + else if (endpoint.getState() == "full") + d->listener->onParticipantDeviceAdded(addr, gruu); + + } } linphone_address_unref(cAddr); } @@ -107,7 +118,7 @@ void RemoteConferenceEventHandler::notifyReceived(string xmlBody) { // ----------------------------------------------------------------------------- -const Address &RemoteConferenceEventHandler::getConfAddress() { +const Address &RemoteConferenceEventHandler::getConfAddress () { L_D(); return d->confAddress; } diff --git a/src/conference/remote-conference-event-handler.h b/src/conference/remote-conference-event-handler.h index fa30dd808..7d25bd359 100644 --- a/src/conference/remote-conference-event-handler.h +++ b/src/conference/remote-conference-event-handler.h @@ -33,14 +33,14 @@ class RemoteConferenceEventHandlerPrivate; class RemoteConferenceEventHandler : public Object { public: - RemoteConferenceEventHandler(LinphoneCore *core, ConferenceListener *listener); - ~RemoteConferenceEventHandler(); + RemoteConferenceEventHandler (LinphoneCore *core, ConferenceListener *listener); + ~RemoteConferenceEventHandler (); - void subscribe(const Address &confAddress); - void notifyReceived(std::string xmlBody); - void unsubscribe(); + void subscribe (const Address &confAddress); + void notifyReceived (std::string xmlBody); + void unsubscribe (); - const Address &getConfAddress(); + const Address &getConfAddress (); private: L_DECLARE_PRIVATE(RemoteConferenceEventHandler);