Commit 2b8291c3 authored by Ghislain MARY's avatar Ghislain MARY
Browse files

Merge remote-tracking branch 'origin/dev_conference_info' into dev_refactor_cpp

parents 93c17c21 4d1e1c8d
......@@ -133,6 +133,7 @@ else()
find_package(Belr REQUIRED)
endif()
find_package(XML2 REQUIRED)
find_package(LibXsd REQUIRED)
find_package(Soci)
find_package(Zlib)
if(ENABLE_TUNNEL)
......
......@@ -33,7 +33,6 @@ if(ANDROID)
find_package(Support REQUIRED)
endif()
list(APPEND LINPHONE_PRIVATE_HEADER_FILES
bellesip_sal/sal_impl.h
carddav.h
......@@ -121,6 +120,7 @@ set(LINPHONE_SOURCE_FILES_C
set(LINPHONE_SOURCE_FILES_CXX
conference.cc
)
set(LINPHONE_INCLUDE_DIRS ${LINPHONE_INCLUDE_DIRS})
if(ANDROID)
list(APPEND LINPHONE_SOURCE_FILES_CXX linphonecore_jni.cc)
set_source_files_properties(linphonecore_jni.cc PROPERTIES COMPILE_DEFINITIONS "USE_JAVAH")
......@@ -157,6 +157,7 @@ set(LIBS
${ORTP_LIBRARIES}
${XML2_LIBRARIES}
${BELR_LIBRARIES}
${LIBXSD_LIBRARIES}
)
if(WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
list(APPEND LIBS "Ws2_32")
......
......@@ -45,6 +45,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "mediastreamer2/msjpegwriter.h"
#include "mediastreamer2/msogl.h"
#include "mediastreamer2/msvolume.h"
#include "conference/remote-conference-event-handler.h"
// For migration purpose.
#include "address/address-p.h"
......@@ -2123,12 +2124,17 @@ static void linphone_core_register_default_codecs(LinphoneCore *lc){
static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *notified_event, const LinphoneContent *body) {
if (strcmp(notified_event, "Presence") == 0) {
const bctbx_list_t* friendLists = linphone_core_get_friends_lists(lc);
while( friendLists != NULL ){
LinphoneFriendList* list = reinterpret_cast<LinphoneFriendList *>(friendLists->data);
ms_message("notify presence for list %p", list);
for (const bctbx_list_t *it = linphone_core_get_friends_lists(lc); it; it = bctbx_list_next(it)) {
LinphoneFriendList *list = reinterpret_cast<LinphoneFriendList *>(bctbx_list_get_data(it));
ms_message("Notify presence for list %p", list);
linphone_friend_list_notify_presence_received(list, lev, body);
friendLists = friendLists->next;
}
} else if (strcmp(notified_event, "Conference") == 0) {
LinphonePrivate::RemoteConferenceEventHandler *handler =
reinterpret_cast<LinphonePrivate::RemoteConferenceEventHandler *>(linphone_event_get_user_data(lev));
if (handler) {
ms_message("Notify event for conference %s", handler->getConfId().c_str());
handler->notifyReceived((char *)linphone_content_get_buffer(body));
}
}
}
......@@ -2136,6 +2142,8 @@ static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEve
static void linphone_core_internal_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) {
if (strcasecmp(linphone_event_get_name(lev), "Presence") == 0) {
linphone_friend_list_subscription_state_changed(lc, lev, state);
} else if (strcmp(linphone_event_get_name(lev), "Conference") == 0) {
}
}
......
......@@ -53,6 +53,7 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
conference/conference-listener.h
conference/conference.h
conference/local-conference.h
conference/local-conference-event-handler.h
conference/params/call-session-params-p.h
conference/params/call-session-params.h
conference/params/media-session-params-p.h
......@@ -60,6 +61,7 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
conference/participant-p.h
conference/participant.h
conference/remote-conference.h
conference/remote-conference-event-handler.h
conference/session/call-session-listener.h
conference/session/call-session-p.h
conference/session/call-session.h
......@@ -93,6 +95,8 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
object/singleton.h
utils/payload-type-handler.h
variant/variant.h
xml/conference-info.h
xml/xml.h
)
set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
......@@ -122,10 +126,12 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
chat/real-time-text-chat-room.cpp
conference/conference.cpp
conference/local-conference.cpp
conference/local-conference-event-handler.cpp
conference/params/call-session-params.cpp
conference/params/media-session-params.cpp
conference/participant.cpp
conference/remote-conference.cpp
conference/remote-conference-event-handler.cpp
conference/session/call-session.cpp
conference/session/media-session.cpp
content/content-type.cpp
......@@ -150,8 +156,15 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
utils/payload-type-handler.cpp
utils/utils.cpp
variant/variant.cpp
xml/conference-info.cpp
xml/xml.cpp
)
ADD_XSD_WRAPPERS(xml/xml "XML XSD - xml.xsd")
ADD_XSD_WRAPPERS(xml/conference-info "Conference info XSD - conference-info.xsd")
ADD_XSD_WRAPPERS(xml/resource-lists "Resourece lists XSD - resource-lists.xsd")
set(LINPHONE_CXX_OBJECTS_INCLUDE_DIRS ${BELR_INCLUDE_DIRS} ${LIBXSD_INCLUDE_DIRS})
set(LINPHONE_CXX_OBJECTS_DEFINITIONS "-DLIBLINPHONE_EXPORTS")
set(LINPHONE_CXX_OBJECTS_INCLUDE_DIRS ${BELR_INCLUDE_DIRS})
......
......@@ -19,19 +19,22 @@
#ifndef _CONFERENCE_LISTENER_H_
#define _CONFERENCE_LISTENER_H_
#include "address/address.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class ConferenceListener {
public:
virtual void onConferenceCreated (LinphoneAddress *addr) = 0;
virtual void onConferenceTerminated (LinphoneAddress *addr) = 0;
virtual void onParticipantAdded (LinphoneAddress *addr) = 0;
virtual void onParticipantRemoved (LinphoneAddress *addr) = 0;
virtual void onParticipantSetAdmin (LinphoneAddress *addr, bool isAdmin) = 0;
virtual void onConferenceCreated (const Address &addr) = 0;
virtual void onConferenceTerminated (const Address &addr) = 0;
virtual void onParticipantAdded (const Address &addr) = 0;
virtual void onParticipantRemoved (const Address &addr) = 0;
virtual void onParticipantSetAdmin (const Address &addr, bool isAdmin) = 0;
};
LINPHONE_END_NAMESPACE
#endif // ifndef _CONFERENCE_LISTENER_H_
......@@ -141,4 +141,14 @@ void Conference::onResetFirstVideoFrameDecoded (const CallSession &session) {
callListener->onResetFirstVideoFrameDecoded();
}
// -----------------------------------------------------------------------------
std::shared_ptr<Participant> Conference::findParticipant (const Address &addr) {
for (const auto &participant : participants) {
if (addr.equal(participant->getAddress()))
return participant;
}
return nullptr;
}
LINPHONE_END_NAMESPACE
......@@ -78,6 +78,8 @@ private:
protected:
explicit Conference (LinphoneCore *core, const Address &myAddress, CallListener *listener = nullptr);
std::shared_ptr<Participant> findParticipant (const Address &addr);
protected:
LinphoneCore *core = nullptr;
CallListener *callListener = nullptr;
......
/*
* local-conference-event-handler.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "conference/local-conference.h"
#include "conference/participant.h"
#include "local-conference-event-handler.h"
#include "object/object-p.h"
#include "xml/conference-info.h"
#include "private.h"
using namespace std;
using namespace conference_info;
using namespace LinphonePrivate;
LINPHONE_BEGIN_NAMESPACE
class LocalConferenceEventHandlerPrivate : public ObjectPrivate {
public:
void notifyFullState(string notify, LinphoneEvent *lev);
void notifyAllExcept(string notify, const Address &addr);
LinphoneCore *core = nullptr;
LocalConference *conf = nullptr;
};
LINPHONE_END_NAMESPACE
void LocalConferenceEventHandlerPrivate::notifyFullState(string notify, LinphoneEvent *lev) {
LinphoneContent *content = linphone_core_create_content(lev->lc);
linphone_content_set_buffer(content, notify.c_str(), strlen(notify.c_str()));
linphone_event_notify(lev, content);
linphone_content_unref(content);
// linphone_event_unref(lev); ??
}
void LocalConferenceEventHandlerPrivate::notifyAllExcept(string notify, const Address &addr) {
for (const auto &participant : conf->getParticipants()) {
if (!addr.equal(participant->getAddress())) {
LinphoneAddress *cAddr = linphone_address_new(participant->getAddress().asString().c_str());
LinphoneEvent *lev = linphone_core_create_notify(core, cAddr, "Conference");
linphone_address_unref(cAddr);
LinphoneContent *content = linphone_core_create_content(lev->lc);
linphone_content_set_buffer(content, notify.c_str(), strlen(notify.c_str()));
linphone_event_notify(lev, content);
linphone_content_unref(content);
linphone_event_unref(lev);
}
}
}
// -------- Conference::LocalConferenceEventHandler public methods ---------
LocalConferenceEventHandler::LocalConferenceEventHandler(LinphoneCore *core, LocalConference *localConf) : Object(*new LocalConferenceEventHandlerPrivate) {
L_D(LocalConferenceEventHandler);
xercesc::XMLPlatformUtils::Initialize();
d->conf = localConf;
d->core = core; // conf->getCore() ?
}
LocalConferenceEventHandler::~LocalConferenceEventHandler() {
xercesc::XMLPlatformUtils::Terminate();
}
string LocalConferenceEventHandler::subscribeReceived(LinphoneEvent *lev) {
L_D(LocalConferenceEventHandler);
string entity = d->conf->getMe()->getAddress().asStringUriOnly();
Conference_type confInfo = Conference_type(entity);
Users_type users;
confInfo.setUsers(users);
xml_schema::NamespaceInfomap map;
map[""].name = "urn:ietf:params:xml:ns:conference-info";
for (const auto &participant : d->conf->getParticipants()) {
User_type user = User_type();
User_roles_type roles;
user.setRoles(roles);
user.setEntity(participant->getAddress().asStringUriOnly());
user.getRoles()->getEntry().push_back(participant->isAdmin() ? "admin" : "participant");
user.setState("full");
confInfo.getUsers()->getUser().push_back(user);
}
stringstream notify;
serializeConference_info(notify, confInfo, map);
//d->notifyFullState(notify.str(), lev);
return notify.str();
}
string LocalConferenceEventHandler::notifyParticipantAdded(const Address &addr) {
L_D(LocalConferenceEventHandler);
string entity = d->conf->getMe()->getAddress().asStringUriOnly();
Conference_type confInfo = Conference_type(entity);
Users_type users;
confInfo.setUsers(users);
User_type user = User_type();
User_roles_type roles;
user.setRoles(roles);
user.setEntity(addr.asStringUriOnly());
user.getRoles()->getEntry().push_back("participant");
user.setState("full");
confInfo.getUsers()->getUser().push_back(user);
xml_schema::NamespaceInfomap map;
stringstream notify;
serializeConference_info(notify, confInfo, map);
//d->notifyAllExcept(notify.str(), addr);
return notify.str();
}
string LocalConferenceEventHandler::notifyParticipantRemoved(const Address &addr) {
L_D(LocalConferenceEventHandler);
string entity = d->conf->getMe()->getAddress().asStringUriOnly();
Conference_type confInfo = Conference_type(entity);
Users_type users;
confInfo.setUsers(users);
User_type user = User_type();
user.setEntity(addr.asStringUriOnly());
user.setState("deleted");
confInfo.getUsers()->getUser().push_back(user);
xml_schema::NamespaceInfomap map;
stringstream notify;
serializeConference_info(notify, confInfo, map);
//d->notifyAllExcept(notify.str(), addr);
return notify.str();
}
string LocalConferenceEventHandler::notifyParticipantSetAdmin(const Address &addr, bool isAdmin) {
L_D(LocalConferenceEventHandler);
string entity = d->conf->getMe()->getAddress().asStringUriOnly();
Conference_type confInfo = Conference_type(entity);
Users_type users;
confInfo.setUsers(users);
User_type user = User_type();
User_roles_type roles;
user.setRoles(roles);
user.setEntity(addr.asStringUriOnly());
user.getRoles()->getEntry().push_back(isAdmin ? "admin" : "participant");
user.setState("partial");
confInfo.getUsers()->getUser().push_back(user);
xml_schema::NamespaceInfomap map;
stringstream notify;
serializeConference_info(notify, confInfo, map);
//d->notifyAllExcept(notify.str(), addr);
return notify.str();
}
/*
* local-conference-event-handler.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LOCAL_CONFERENCE_EVENT_HANDLER_H_
#define _LOCAL_CONFERENCE_EVENT_HANDLER_H_
#include <string>
#include "linphone/types.h"
#include "address/address.h"
#include "object/object.h"
LINPHONE_BEGIN_NAMESPACE
class LocalConference;
class LocalConferenceEventHandlerPrivate;
class LocalConferenceEventHandler : public Object {
public:
LocalConferenceEventHandler(LinphoneCore *core, LocalConference *localConf);
~LocalConferenceEventHandler();
std::string subscribeReceived(LinphoneEvent *lev);
std::string notifyParticipantAdded(const Address &addr);
std::string notifyParticipantRemoved(const Address &addr);
std::string notifyParticipantSetAdmin(const Address &addr, bool isAdmin);
private:
L_DECLARE_PRIVATE(LocalConferenceEventHandler);
L_DISABLE_COPY(LocalConferenceEventHandler);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _LOCAL_CONFERENCE_EVENT_HANDLER_H_
......@@ -17,12 +17,67 @@
*/
#include "local-conference.h"
#include "participant-p.h"
LINPHONE_BEGIN_NAMESPACE
using namespace std;
using namespace LinphonePrivate;
// =============================================================================
LocalConference::LocalConference (LinphoneCore *core, const Address &myAddress, CallListener *listener)
: Conference(core, myAddress, listener) {}
: Conference(core, myAddress, listener) {
eventHandler = new LocalConferenceEventHandler(core, this);
}
LINPHONE_END_NAMESPACE
LocalConference::~LocalConference () {
delete eventHandler;
}
// -----------------------------------------------------------------------------
shared_ptr<Participant> LocalConference::addParticipant (const Address &addr, const CallSessionParams *params, bool hasMedia) {
shared_ptr<Participant> participant = findParticipant(addr);
if (participant)
return participant;
participant = make_shared<Participant>(addr);
participant->getPrivate()->createSession(*this, params, hasMedia, this);
participants.push_back(participant);
activeParticipant = participant;
return participant;
}
void LocalConference::addParticipants (const list<Address> &addresses, const CallSessionParams *params, bool hasMedia) {
for (const auto &addr : addresses)
addParticipant(addr, params, hasMedia);
}
bool LocalConference::canHandleParticipants () const {
return true;
}
const string& LocalConference::getId () const {
return id;
}
int LocalConference::getNbParticipants () const {
participants.size();
return 1;
}
list<shared_ptr<Participant>> LocalConference::getParticipants () const {
return participants;
}
void LocalConference::removeParticipant (const shared_ptr<Participant> participant) {
for (const auto &p : participants) {
if (participant->getAddress().equal(p->getAddress())) {
participants.remove(p);
return;
}
}
}
void LocalConference::removeParticipants (const list<shared_ptr<Participant>> participants) {
for (const auto &p : participants)
removeParticipant(p);
}
......@@ -20,6 +20,7 @@
#define _LOCAL_CONFERENCE_H_
#include "conference.h"
#include "local-conference-event-handler.h"
// =============================================================================
......@@ -28,10 +29,25 @@ LINPHONE_BEGIN_NAMESPACE
class LocalConference : public Conference {
public:
LocalConference (LinphoneCore *core, const Address &myAddress, CallListener *listener = nullptr);
virtual ~LocalConference() = default;
virtual ~LocalConference();
LocalConferenceEventHandler * getEventHandler() const { return eventHandler; }
public:
/* ConferenceInterface */
virtual std::shared_ptr<Participant> addParticipant (const Address &addr, const CallSessionParams *params, bool hasMedia);
virtual void addParticipants (const std::list<Address> &addresses, const CallSessionParams *params, bool hasMedia);
virtual bool canHandleParticipants () const;
virtual const std::string& getId () const;
virtual int getNbParticipants () const;
virtual std::list<std::shared_ptr<Participant>> getParticipants () const;
virtual void removeParticipant (const std::shared_ptr<Participant> participant);
virtual void removeParticipants (const std::list<std::shared_ptr<Participant>> participants);
private:
L_DISABLE_COPY(LocalConference);
LocalConferenceEventHandler *eventHandler = nullptr;
};
LINPHONE_END_NAMESPACE
......
......@@ -36,6 +36,7 @@ class Participant : public Object {
friend class CallPrivate;
friend class ClientGroupChatRoom;
friend class Conference;
friend class LocalConference;
friend class MediaSessionPrivate;
public:
......
/*
* remote-conference-event-handler.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "remote-conference-event-handler.h"
#include "xml/conference-info.h"
#include "private.h"
#include "object/object-p.h"
using namespace std;
using namespace conference_info;
using namespace LinphonePrivate;
LINPHONE_BEGIN_NAMESPACE
class RemoteConferenceEventHandlerPrivate : public ObjectPrivate {
public:
LinphoneCore *core = nullptr;
ConferenceListener *listener = nullptr;
Address confAddr;
string confId;
LinphoneEvent *lev = nullptr;
};
LINPHONE_END_NAMESPACE
// -------- RemoteConferenceEventHandler public methods ---------
RemoteConferenceEventHandler::RemoteConferenceEventHandler(LinphoneCore *core, ConferenceListener *listener, const Address &confAddr) : Object(*new RemoteConferenceEventHandlerPrivate) {
L_D(RemoteConferenceEventHandler);
xercesc::XMLPlatformUtils::Initialize();
d->core = core;
d->listener = listener;
d->confAddr = confAddr;
}
RemoteConferenceEventHandler::~RemoteConferenceEventHandler() {
L_D(RemoteConferenceEventHandler);
xercesc::XMLPlatformUtils::Terminate();
if (d->lev)
linphone_event_unref(d->lev);
}
void RemoteConferenceEventHandler::subscribe(string confId) {
L_D(RemoteConferenceEventHandler);
d->confId = confId;
LinphoneAddress *addr = linphone_address_new(d->confAddr.asString().c_str());
d->lev = linphone_core_create_subscribe(d->core, addr, "Conference", 600);
linphone_address_unref(addr);
linphone_event_ref(d->lev);
linphone_event_set_internal(d->lev, TRUE);
linphone_event_set_user_data(d->lev, this);
linphone_event_add_custom_header(d->lev, "Conf-id", d->confId.c_str()); // TODO : ???
linphone_event_send_subscribe(d->lev, nullptr);
}
void RemoteConferenceEventHandler::unsubscribe() {
L_D(RemoteConferenceEventHandler);
linphone_event_terminate(d->lev);
}
void RemoteConferenceEventHandler::notifyReceived(string xmlBody) {
L_D(RemoteConferenceEventHandler);
istringstream data(xmlBody);
unique_ptr<Conference_type> confInfo = parseConference_info(data, xml_schema::Flags::dont_validate);
if (confInfo->getEntity() == d->confAddr.asString()) {
for (const auto &user : confInfo->getUsers()->getUser()) {
LinphoneAddress *cAddr = linphone_core_interpret_url(d->core, user.getEntity()->c_str());
Address addr(linphone_address_as_string(cAddr));
if (user.getState() == "deleted")
d->listener->onParticipantRemoved(addr);
else {