Commit 5016cc29 authored by Simon Morlat's avatar Simon Morlat
Browse files

Modify ServerGroupChatRoom behavior about 1-1 chatroom, incrementing "groupchat" capability to 1.1

Previously, a 1-1 chatroom was deleted only if it were BYEd by every device. A device that BYEd previously was re-INVITED by the chatroom in case messages had to be delivered. In addition, a device that BYEd the chatroom was given back the same chatroom ID when trying to re-create a new chatroom to the same other participant.
Doing all this required to store 1-1 chatroom in a specific table, so that they could be retrieved fastly.
Unfortunately this design totally breaks a federated system, since each domain may be entitled to create a 1-1 chatroom to communicate with a participant from another domain. As a result, the unicity of the one to one chatroom is not achievable in a federation of SIP domains.

Now, the ServerGroupChatRoom conforming to groupchat/1.1 treats 1-1 chatroom similarly as real group chat rooms, with only one exception: when a device leaves the chatroom, then the chatroom is terminated, ie the server sends BYE to every device.
In contrat, the client are then expected to restart the INVITE procedure if they want to send message through a chatroom whose session has been terminated by a BYE. The chatroom ID will of course change.

Thanks to "org.linphone.specs" (capability descriptor), backward compatibility is preserved: the ServerGroupChatRoom keeps the old behaviour if one of the device doesn't conform to 1.1 specification.
parent 60585a9c
......@@ -11,7 +11,6 @@ This changelog file was started on October 2019. Previous changes were more or l
## [Unreleased]
### Added
- RTP bundle mode feature according to https://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-54 .
- EnterForeground and enterBackground automatically for ios and anroid.
- Audio routes API to choose which device use to capture & play audio on Android & iOS.
- Handling push notifications, activity monitor and Core iterate automatically in Core for Android.
......@@ -21,6 +20,10 @@ This changelog file was started on October 2019. Previous changes were more or l
### Changed
- Improved Android network manager.
- to make it consistent with other liblinphone's object, linphone_core_create_subscribe(), linphone_core_create_subscribe2(),
linphone_core_create_publish() now give ownership of the returned LinphoneEvent, which means that it is no longer need to call
linphone_event_ref() after calling these functions. As a consequence, an application not using linphone_event_ref() should now
use linphone_event_unref() when the LinphoneEvent is no longer used, otherwise it will create a memory leak.
### Fixed
- Internal refactoring of management of locally played tones, in order to fix race conditions.
......
......@@ -744,6 +744,7 @@ static void notify(SalSubscribeOp *op, SalSubscribeStatus st, const char *eventn
if (out_of_dialog) {
/*out of dialog notify */
lev = linphone_event_new_with_out_of_dialog_op(lc,op,LinphoneSubscriptionOutgoing,eventname);
lev->unref_when_terminated = TRUE;
}
{
LinphoneContent *ct = linphone_content_from_sal_body_handler(body_handler);
......@@ -756,7 +757,10 @@ static void notify(SalSubscribeOp *op, SalSubscribeStatus st, const char *eventn
/*out of dialog NOTIFY do not create an implicit subscription*/
linphone_event_set_state(lev, LinphoneSubscriptionTerminated);
}else if (st!=SalSubscribeNone){
linphone_event_set_state(lev,linphone_subscription_state_from_sal(st));
/* Take into account that the subscription may have been closed by app already within linphone_core_notify_notify_received() */
if (linphone_event_get_subscription_state(lev) != LinphoneSubscriptionTerminated){
linphone_event_set_state(lev,linphone_subscription_state_from_sal(st));
}
}
}
......@@ -769,6 +773,7 @@ static void subscribe_received(SalSubscribeOp *op, const char *eventname, const
if (lev==NULL) {
lev=linphone_event_new_with_op(lc,op,LinphoneSubscriptionIncoming,eventname);
lev->unref_when_terminated = TRUE;
linphone_event_set_state(lev,LinphoneSubscriptionIncomingReceived);
LinphoneContent *ct = linphone_content_from_sal_body_handler(body_handler);
Address to(op->getTo());
......
/*
* Copyright (c) 2010-2019 Belledonne Communications SARL.
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of Liblinphone.
*
......@@ -17,21 +17,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <libxml/parser.h>
#include <libxml/tree.h>
......
......@@ -121,7 +121,9 @@ static void linphone_event_release(LinphoneEvent *lev){
/*this will stop the refresher*/
lev->op->stopRefreshing();
}
linphone_event_unref(lev);
if (lev->unref_when_terminated) {
linphone_event_unref(lev);
}
}
static LinphoneEvent * linphone_event_new_base(LinphoneCore *lc, LinphoneSubscriptionDir dir, const char *name, LinphonePrivate::SalEventOp *op){
......@@ -169,10 +171,12 @@ void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState stat
if (lev && lev->subscription_state!=state){
ms_message("LinphoneEvent [%p] moving to subscription state %s",lev,linphone_subscription_state_to_string(state));
lev->subscription_state=state;
linphone_event_ref(lev);
linphone_core_notify_subscription_state_changed(lev->lc,lev,state);
if (state==LinphoneSubscriptionTerminated || state == LinphoneSubscriptionError){
linphone_event_release(lev);
}
linphone_event_unref(lev);
}
}
......@@ -245,6 +249,7 @@ LinphoneEvent *linphone_core_create_notify(LinphoneCore *lc, const LinphoneAddre
LinphoneEvent *linphone_core_subscribe(LinphoneCore *lc, const LinphoneAddress *resource, const char *event, int expires, const LinphoneContent *body){
LinphoneEvent *lev=linphone_core_create_subscribe(lc,resource,event,expires);
lev->unref_when_terminated = TRUE;
linphone_event_send_subscribe(lev,body);
return lev;
}
......@@ -391,6 +396,7 @@ static int _linphone_event_send_publish(LinphoneEvent *lev, const LinphoneConten
LinphoneEvent *linphone_core_publish(LinphoneCore *lc, const LinphoneAddress *resource, const char *event, int expires, const LinphoneContent *body){
int err;
LinphoneEvent *lev=linphone_core_create_publish(lc,resource,event,expires);
lev->unref_when_terminated = TRUE;
err=_linphone_event_send_publish(lev,body,FALSE);
if (err==-1){
linphone_event_unref(lev);
......
......@@ -1017,7 +1017,6 @@ static void _linphone_friend_list_send_list_subscription_with_body(LinphoneFrien
linphone_event_unref(list->event);
}
list->event = linphone_core_create_subscribe(list->lc, address, "presence", expires);
linphone_event_ref(list->event);
linphone_event_set_internal(list->event, TRUE);
linphone_event_add_custom_header(list->event, "Require", "recipient-list-subscribe");
linphone_event_add_custom_header(list->event, "Supported", "eventlist");
......@@ -1054,7 +1053,6 @@ static void _linphone_friend_list_send_list_subscription_without_body(LinphoneFr
linphone_event_unref(list->event);
}
list->event = linphone_core_create_subscribe(list->lc, address, "presence", expires);
linphone_event_ref(list->event);
linphone_event_set_internal(list->event, TRUE);
linphone_event_add_custom_header(list->event, "Supported", "eventlist");
linphone_event_add_custom_header(list->event, "Accept", "multipart/related, application/pidf+xml, application/rlmi+xml");
......
......@@ -7946,23 +7946,28 @@ void linphone_core_enable_conference_server (LinphoneCore *lc, bool_t enable) {
}
bool_t _linphone_core_is_conference_creation (const LinphoneCore *lc, const LinphoneAddress *addr) {
LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(lc);
if (!proxy)
return FALSE;
const char *uri = linphone_proxy_config_get_conference_factory_uri(proxy);
if (!uri)
return FALSE;
LinphoneAddress *factoryAddr = linphone_address_new(uri);
if (!factoryAddr)
return FALSE;
// Do not compare ports
linphone_address_set_port(factoryAddr, 0);
const bctbx_list_t * elem;
LinphoneAddress *testedAddr = linphone_address_clone(addr);
bool_t result = FALSE;
if (!testedAddr) return FALSE;
linphone_address_set_port(testedAddr, 0);
bool_t result = linphone_address_weak_equal(factoryAddr, testedAddr);
linphone_address_unref(factoryAddr);
for (elem = linphone_core_get_proxy_config_list(lc); elem != NULL; elem = elem->next){
LinphoneProxyConfig *proxy = (LinphoneProxyConfig*) elem->data;
const char *uri = linphone_proxy_config_get_conference_factory_uri(proxy);
if (!uri) continue;
LinphoneAddress *factoryAddr = linphone_address_new(uri);
if (!factoryAddr) continue;
// Do not compare ports
linphone_address_set_port(factoryAddr, 0);
result = linphone_address_weak_equal(factoryAddr, testedAddr);
linphone_address_unref(factoryAddr);
if (result) break; /* if they match*/
}
linphone_address_unref(testedAddr);
return result;
}
......
......@@ -411,17 +411,18 @@ struct _LinphoneEvent{
bctbx_list_t *callbacks_list;
LinphoneEventCbs *currentCbs;
int expires;
bool_t terminating;
bool_t is_out_of_dialog_op; /*used for out of dialog notify*/
bool_t internal;
bool_t oneshot;
// For migration purpose. (Do not use directly!)
// Cache.
LinphoneAddress *to_address;
LinphoneAddress *from_address;
LinphoneAddress *remote_contact_address;
int expires;
bool_t terminating;
bool_t is_out_of_dialog_op; /*used for out of dialog notify*/
bool_t internal;
bool_t oneshot;
bool_t unref_when_terminated;
};
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneEvent);
......
......@@ -974,7 +974,6 @@ int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePrese
proxy->presence_publish_event = linphone_proxy_config_create_publish(proxy
, "presence"
, linphone_proxy_config_get_publish_expires(proxy));
linphone_event_ref(proxy->presence_publish_event);
}
proxy->presence_publish_event->internal = TRUE;
......
......@@ -389,7 +389,6 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report,
}
if (linphone_event_send_publish(lev, content) != 0){
lev=NULL;
ret=4;
} else {
reset_avg_metrics(report);
......@@ -399,7 +398,7 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report,
STR_REASSIGN(report->qos_analyzer.output_leg, NULL);
STR_REASSIGN(report->qos_analyzer.output, NULL);
}
linphone_event_unref(lev);
linphone_address_unref(request_uri);
linphone_content_unref(content);
if (collector_uri_allocated) ms_free(collector_uri_allocated);
......
......@@ -22,10 +22,13 @@
#include "linphone/core.h"
#include "linphone/logging.h"
#include "linphone/lpconfig.h"
#include "linphone/utils/utils.h"
#include "private.h"
#include "logging-private.h"
using namespace LinphonePrivate;
LinphoneUpdateCheck * linphone_update_check_new(LinphoneCore *lc, const char *version, belle_http_request_listener_t *listener) {
LinphoneUpdateCheck *update = ms_new0(LinphoneUpdateCheck, 1);
......@@ -49,44 +52,8 @@ static void update_check_process_terminated(LinphoneUpdateCheck *update, Linphon
linphone_update_check_destroy(update);
}
typedef struct _parsed_version_st {
int major;
int minor;
int patch;
} parsed_version_t;
static int compare_parsed_versions(parsed_version_t current_version, parsed_version_t last_version) {
bool same_major = (last_version.major == current_version.major);
bool same_minor = (last_version.minor == current_version.minor);
if (last_version.major > current_version.major) return 1;
if (same_major && last_version.minor > current_version.minor) return 1;
if (same_minor && last_version.patch > current_version.patch) return 1;
return -1;
}
static void parse_version(const char *version, parsed_version_t *parsed_version) {
char *copy = bctbx_strdup(version);
char *ptr = copy;
char *next;
memset(parsed_version, 0, sizeof(parsed_version_t));
next = strchr(ptr, '.');
parsed_version->major = atoi(ptr);
ptr = next + 1;
next = strchr(ptr, '.');
parsed_version->minor = atoi(ptr);
if (next != NULL) {
ptr = next + 1;
parsed_version->patch = atoi(ptr);
}
bctbx_free(copy);
}
static bool_t update_is_available(const char *current_version, const char *last_version) {
parsed_version_t current_parsed_version;
parsed_version_t last_parsed_version;
parse_version(current_version, &current_parsed_version);
parse_version(last_version, &last_parsed_version);
return (compare_parsed_versions(current_parsed_version, last_parsed_version) > 0) ? TRUE : FALSE;
return Utils::Version(current_version) < Utils::Version(last_version);
}
static void update_check_process_response_event(void *ctx, const belle_http_response_event_t *event) {
......
......@@ -41,13 +41,6 @@
**/
LINPHONE_PUBLIC LinphoneParticipantDeviceIdentity *linphone_participant_device_identity_new (const LinphoneAddress *address, const char *name);
/**
* Clones a #LinphoneParticipantDeviceIdentity object.
* @param device_identity the #LinphoneParticipantDeviceIdentity object @notnil
* @return a cloned #LinphoneParticipantDeviceIdentity object @notnil
**/
LINPHONE_PUBLIC LinphoneParticipantDeviceIdentity *linphone_participant_device_identity_clone (const LinphoneParticipantDeviceIdentity *device_identity);
/**
* Increment reference count of #LinphoneParticipantDeviceIdentity object.
* @param device_identity the #LinphoneParticipantDeviceIdentity object @notnil
......@@ -61,6 +54,30 @@ LINPHONE_PUBLIC LinphoneParticipantDeviceIdentity *linphone_participant_device_i
**/
LINPHONE_PUBLIC void linphone_participant_device_identity_unref (LinphoneParticipantDeviceIdentity *device_identity);
/**
* Set the capability descriptor (currently +org.linphone.specs value) for this participant device identity.
* @param device_identity the #LinphoneParticipantDeviceIdentity object @notnil
* @param capability_descriptor the capability descriptor string.
*
**/
LINPHONE_PUBLIC void linphone_participant_device_identity_set_capability_descriptor(LinphoneParticipantDeviceIdentity *device_identity, const char *capability_descriptor);
/**
* Get the capability descriptor (currently +org.linphone.specs value) for this participant device identity.
* @param device_identity the #LinphoneParticipantDeviceIdentity object @notnil
* @return the capability descriptor string.
*
**/
LINPHONE_PUBLIC const char* linphone_participant_device_identity_get_capability_descriptor(const LinphoneParticipantDeviceIdentity *device_identity);
/**
* Get the address of the participant device.
* @param device_identity the #LinphoneParticipantDeviceIdentity @notnil
* @return the address. @notnil
*/
LINPHONE_PUBLIC const LinphoneAddress* linphone_participant_device_identity_get_address(const LinphoneParticipantDeviceIdentity *deviceIdentity);
/**
* @}
*/
......
......@@ -186,15 +186,14 @@ LINPHONE_PUBLIC const char *linphone_event_get_custom_header(LinphoneEvent *linp
/**
* Terminate an incoming or outgoing subscription that was previously acccepted, or a previous publication.
* The #LinphoneEvent shall not be used anymore after this operation, unless the application explicitely took a reference on the object with
* linphone_event_ref().
* The #LinphoneEvent shall not be used anymore after this operation.
* @param linphone_event #LinphoneEvent object @notnil
**/
LINPHONE_PUBLIC void linphone_event_terminate(LinphoneEvent *linphone_event);
/**
* Increase reference count of LinphoneEvent.
* By default #LinphoneEvents created by the core are owned by the core only.
* A #LinphoneEvent created by the core when receiving an incoming SUBSCRIBE or PUBLISH are owned by the core only.
* An application that wishes to retain a reference to it must call linphone_event_ref().
* When this reference is no longer needed, linphone_event_unref() must be called.
* @param linphone_event #LinphoneEvent object @notnil
......
......@@ -26,6 +26,7 @@
#include <string>
#include <utility>
#include <vector>
#include <map>
#include "linphone/utils/enum-generator.h"
......@@ -154,8 +155,47 @@ namespace Utils {
LINPHONE_PUBLIC std::string utf8ToLocale (const std::string &str);
LINPHONE_PUBLIC std::string convertAnyToUtf8 (const std::string &str, const std::string &encoding);
LINPHONE_PUBLIC std::string quoteStringIfNotAlready(const std::string &str);
class Version{
public:
LINPHONE_PUBLIC Version() = default;
LINPHONE_PUBLIC Version(int major, int minor);
LINPHONE_PUBLIC Version(int major, int minor, int patch);
LINPHONE_PUBLIC Version(const std::string &version);
LINPHONE_PUBLIC int compare(const Version &other) const;
LINPHONE_PUBLIC inline bool operator<(const Version &other)const{
return compare(other) < 0;
}
LINPHONE_PUBLIC inline bool operator<=(const Version &other)const{
return compare(other) <= 0;
}
LINPHONE_PUBLIC inline bool operator>(const Version &other)const{
return compare(other) > 0;
}
LINPHONE_PUBLIC inline bool operator>=(const Version &other)const{
return compare(other) >= 0;
}
LINPHONE_PUBLIC inline bool operator==(const Version &other)const{
return compare(other) == 0;
}
LINPHONE_PUBLIC inline int getMajor()const {return mMajor;};
LINPHONE_PUBLIC inline int getMinor()const {return mMinor;};
LINPHONE_PUBLIC inline int getPatch()const {return mPatch;};
private:
int mMajor = 0, mMinor = 0, mPatch = 0;
};
/**
* Parse a capability descriptor string such our org.linphone.specs, made of comma separated keyword with optional version numbers:
* "lime,groupchat/1.1,ephemeral". If absent, the version number is arbitrary supposed to be 1.0.
*/
LINPHONE_PUBLIC std::map<std::string, Version> parseCapabilityDescriptor(const std::string &descriptor);
}
LINPHONE_PUBLIC std::ostream &operator<<(std::ostream & ostr, const Utils::Version &version);
LINPHONE_END_NAMESPACE
#endif // ifndef _L_UTILS_H_
......@@ -420,6 +420,7 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
utils/payload-type-handler.cpp
utils/utils.cpp
utils/if-addrs.cpp
utils/version.cpp
variant/variant.cpp
)
......
......@@ -447,7 +447,7 @@ void linphone_chat_room_set_conference_address (LinphoneChatRoom *cr, const Linp
void linphone_chat_room_set_participant_devices (LinphoneChatRoom *cr, const LinphoneAddress *partAddr, const bctbx_list_t *deviceIdentities) {
#ifdef HAVE_ADVANCED_IM
char *addrStr = linphone_address_as_string(partAddr);
list<LinphonePrivate::ParticipantDeviceIdentity> lDevicesIdentities = L_GET_RESOLVED_CPP_LIST_FROM_C_LIST(deviceIdentities, ParticipantDeviceIdentity);
list<shared_ptr<LinphonePrivate::ParticipantDeviceIdentity>> lDevicesIdentities = LinphonePrivate::ParticipantDeviceIdentity::getCppListFromCList(deviceIdentities);
LinphonePrivate::ServerGroupChatRoomPrivate *sgcr = dynamic_cast<LinphonePrivate::ServerGroupChatRoomPrivate *>(L_GET_PRIVATE_FROM_C_OBJECT(cr));
if (sgcr)
sgcr->setParticipantDevices(LinphonePrivate::IdentityAddress(addrStr), lDevicesIdentities);
......
......@@ -24,40 +24,25 @@
#ifdef HAVE_ADVANCED_IM
#include "chat/chat-room/server-group-chat-room-p.h"
#endif
#include "c-wrapper/c-wrapper.h"
// =============================================================================
#ifdef HAVE_ADVANCED_IM
L_DECLARE_C_CLONABLE_OBJECT_IMPL(ParticipantDeviceIdentity);
#endif
using namespace std;
using namespace LinphonePrivate;
// =============================================================================
LinphoneParticipantDeviceIdentity *linphone_participant_device_identity_new (const LinphoneAddress *address, const char *name) {
#ifdef HAVE_ADVANCED_IM
LinphonePrivate::ParticipantDeviceIdentity *cppPtr = new LinphonePrivate::ParticipantDeviceIdentity(
*L_GET_CPP_PTR_FROM_C_OBJECT(address),
L_C_TO_STRING(name)
);
LinphoneParticipantDeviceIdentity *object = L_INIT(ParticipantDeviceIdentity);
L_SET_CPP_PTR_FROM_C_OBJECT(object, cppPtr);
return object;
return ParticipantDeviceIdentity::createCObject(*L_GET_CPP_PTR_FROM_C_OBJECT(address), name);
#else
return NULL;
#endif
}
LinphoneParticipantDeviceIdentity *linphone_participant_device_identity_clone (const LinphoneParticipantDeviceIdentity *deviceIdentity) {
#ifdef HAVE_ADVANCED_IM
return reinterpret_cast<LinphoneParticipantDeviceIdentity *>(belle_sip_object_clone(BELLE_SIP_OBJECT(deviceIdentity)));
#else
return NULL;
#endif
}
LinphoneParticipantDeviceIdentity *linphone_participant_device_identity_ref (LinphoneParticipantDeviceIdentity *deviceIdentity) {
#ifdef HAVE_ADVANCED_IM
......@@ -73,3 +58,25 @@ void linphone_participant_device_identity_unref (LinphoneParticipantDeviceIdenti
belle_sip_object_unref(deviceIdentity);
#endif
}
void linphone_participant_device_identity_set_capability_descriptor(LinphoneParticipantDeviceIdentity *deviceIdentity, const char *descriptor){
#ifdef HAVE_ADVANCED_IM
ParticipantDeviceIdentity::toCpp(deviceIdentity)->setCapabilityDescriptor(descriptor);
#endif
}
const char* linphone_participant_device_identity_get_capability_descriptor(const LinphoneParticipantDeviceIdentity *deviceIdentity){
#ifdef HAVE_ADVANCED_IM
return ParticipantDeviceIdentity::toCpp(deviceIdentity)->getCapabilityDescriptor().c_str();
#endif
return NULL;
}
const LinphoneAddress* linphone_participant_device_identity_get_address(const LinphoneParticipantDeviceIdentity *deviceIdentity){
#ifdef HAVE_ADVANCED_IM
return ParticipantDeviceIdentity::toCpp(deviceIdentity)->getLinphoneAddress();
#endif
return NULL;
}
......@@ -32,31 +32,37 @@
#include "object/clonable-object.h"
#include "object/clonable-object-p.h"
#include "linphone/utils/utils.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class ParticipantDevice;
class ParticipantDeviceIdentityPrivate : public ClonableObjectPrivate {
public:
Address deviceAddress;
std::string deviceName;
};
class ParticipantDeviceIdentity : public ClonableObject {
class ParticipantDeviceIdentity : public bellesip::HybridObject<LinphoneParticipantDeviceIdentity, ParticipantDeviceIdentity> {
public:
ParticipantDeviceIdentity (const Address &address, const std::string &name);
ParticipantDeviceIdentity (const ParticipantDeviceIdentity &other);
ParticipantDeviceIdentity* clone () const override {
return new ParticipantDeviceIdentity(*this);
ParticipantDeviceIdentity(const Address &address, const std::string &name);
void setCapabilityDescriptor(const std::string & capabilities);
const Address &getAddress () const{
return mDeviceAddress;
}
const Address &getAddress () const;
const std::string &getName () const;
const LinphoneAddress *getLinphoneAddress () const{
return mDeviceAddressCache;
}
const std::string &getName () const{
return mDeviceName;
}
const std::string &getCapabilityDescriptor()const{
return mCapabilityDescriptor;
}
virtual ~ParticipantDeviceIdentity();
private:
L_DECLARE_PRIVATE(ParticipantDeviceIdentity);
Address mDeviceAddress;
LinphoneAddress *mDeviceAddressCache; // To be removed once Address becomes an HybridObject.
std::string mDeviceName;
std::string mCapabilityDescriptor; // +org.linphone.specs capability descriptor
};
class ServerGroupChatRoomPrivate : public ChatRoomPrivate {
......@@ -72,6 +78,8 @@ public:
std::shared_ptr<Participant> findAuthorizedParticipant (const IdentityAddress &participantAddress) const;
void setParticipantDeviceState (const std::shared_ptr<ParticipantDevice> &device, ParticipantDevice::State state);
// Find the other participant of a 1-1 chatroom.
std::shared_ptr<Participant> getOtherParticipant(const std::shared_ptr<Participant> someParticipant) const;
void acceptSession (const std::shared_ptr<CallSession> &session);
// we go here when receiving the first INVITE, the one that will redirect to newly allocated conference URI.
......@@ -90,8 +98,8 @@ public:
void handleSubjectChange(SalCallOp *op);
void setConferenceAddress (const ConferenceAddress &conferenceAddress);
void updateParticipantDevices (const IdentityAddress &addr, const std::list<ParticipantDeviceIdentity> &devices);
void setParticipantDevicesAtCreation(const IdentityAddress &addr, const std::list<ParticipantDeviceIdentity> &devices);
void updateParticipantDevices (const IdentityAddress &addr, const std::list<std::shared_ptr<ParticipantDeviceIdentity>> &devices);
void setParticipantDevicesAtCreation(const IdentityAddress &addr, const std::list<std::shared_ptr<ParticipantDeviceIdentity>> &devices);
void updateParticipantDeviceSession(const std::shared_ptr<ParticipantDevice> &device, bool freslyRegistered = false);
void updateParticipantsSessions();
void conclude();
......@@ -100,7 +108,7 @@ public:
LinphoneReason onSipMessageReceived (SalOp *op, const SalMessage *message) override;
/*These are the two methods called by the registration subscription module*/
void setParticipantDevices(const IdentityAddress &addr, const std::list<ParticipantDeviceIdentity> &devices);
void setParticipantDevices(const IdentityAddress &addr, const std::list<std::shared_ptr<ParticipantDeviceIdentity>> &devices);
void notifyParticipantDeviceRegistration(const IdentityAddress &participantDevice);
private:
......@@ -128,7 +136,7 @@ private:
static void copyMessageHeaders (const std::shared_ptr<Message> &fromMessage, const std::shared_ptr<ChatMessage> &toMessage);
static bool allDevicesLeft(const std::shared_ptr<Participant> &participant);
void addParticipantDevice (const std::shared_ptr<Participant> &participant, const ParticipantDeviceIdentity &deviceInfo);
void addParticipantDevice (const std::shared_ptr<Participant> &participant, const std::shared_ptr<ParticipantDeviceIdentity> &deviceInfo);
void designateAdmin ();
void sendMessage (const std::shared_ptr<Message> &message, const IdentityAddress &deviceAddr);
void finalizeCreation ();
......@@ -141,6 +149,9 @@ private:
void removeParticipantDevice (const std::shared_ptr<Participant> &participant, const IdentityAddress &deviceAddress);
void onParticipantDeviceLeft (const std::shared_ptr<ParticipantDevice> &device);
void onBye(const std::shared_ptr<ParticipantDevice> &participantLeaving);
void determineProtocolVersion();
void updateProtocolVersionFromDevice(const std::shared_ptr<ParticipantDevice> &device);
// ChatRoomListener