Merge fix for client group chat room

This commit is contained in:
Erwan Croze 2017-10-27 13:44:42 +02:00
parent bd9af1601e
commit 64e550f764
19 changed files with 552 additions and 18 deletions

View file

@ -40,6 +40,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "c-wrapper/c-wrapper.h"
#include "call/call-p.h"
#include "chat/chat-room/chat-room.h"
#include "chat/chat-room/server-group-chat-room-p.h"
#include "conference/participant.h"
#include "conference/session/call-session-p.h"
#include "conference/session/call-session.h"
@ -115,6 +116,28 @@ static void call_received(SalCallOp *h) {
fromAddr = linphone_address_new(h->get_from());
LinphoneAddress *toAddr = linphone_address_new(h->get_to());
if (_linphone_core_is_conference_creation(lc, toAddr)) {
if (sal_address_has_param(h->get_remote_contact_address(), "text"))
_linphone_core_create_server_group_chat_room(lc, h);
// TODO: handle media conference creation if the "text" feature tag is not present
linphone_address_unref(toAddr);
linphone_address_unref(fromAddr);
return;
} else if (sal_address_has_param(h->get_remote_contact_address(), "text")) {
linphone_address_unref(toAddr);
linphone_address_unref(fromAddr);
LinphonePrivate::Address addr(h->get_to());
if (addr.isValid()) {
LinphoneChatRoom *cr = _linphone_core_find_group_chat_room(lc, addr.asStringUriOnly().c_str());
if (cr) {
L_GET_PRIVATE_FROM_C_OBJECT(cr, ServerGroupChatRoom)->confirmJoining(h);
return;
}
}
} else {
// TODO: handle media conference joining if the "text" feature tag is not present
}
/* First check if we can answer successfully to this invite */
LinphonePresenceActivity *activity = nullptr;
if ((linphone_presence_model_get_basic_status(lc->presence_model) == LinphonePresenceBasicStatusClosed)
@ -720,18 +743,38 @@ static void on_notify_response(SalOp *op){
static void refer_received(SalOp *op, const SalAddress *refer_to){
if (sal_address_has_param(refer_to, "text")) {
LinphonePrivate::Address addr(sal_address_as_string(refer_to));
char *refer_uri = sal_address_as_string(refer_to);
LinphonePrivate::Address addr(refer_uri);
bctbx_free(refer_uri);
if (addr.isValid()) {
LinphoneCore *lc = reinterpret_cast<LinphoneCore *>(op->get_sal()->get_user_pointer());
if (addr.hasUriParam("method") && (addr.getUriParamValue("method") == "BYE")) {
// The server asks a participant to leave a chat room
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(lc->cppCore->findChatRoom(addr));
if (cr) {
L_GET_CPP_PTR_FROM_C_OBJECT(cr)->leave();
static_cast<SalReferOp *>(op)->reply(SalReasonNone);
return;
if (linphone_core_conference_server_enabled(lc)) {
// Removal of a participant at the server side
LinphoneChatRoom *cr = _linphone_core_find_group_chat_room(lc, op->get_to());
if (cr) {
Address fromAddr(op->get_from());
std::shared_ptr<Participant> participant = L_GET_CPP_PTR_FROM_C_OBJECT(cr)->findParticipant(fromAddr);
if (!participant || !participant->isAdmin()) {
static_cast<SalReferOp *>(op)->reply(SalReasonDeclined);
return;
}
participant = L_GET_CPP_PTR_FROM_C_OBJECT(cr)->findParticipant(addr);
if (participant)
L_GET_CPP_PTR_FROM_C_OBJECT(cr)->removeParticipant(participant);
static_cast<SalReferOp *>(op)->reply(SalReasonNone);
return;
}
} else {
// The server asks a participant to leave a chat room
LinphoneChatRoom *cr = _linphone_core_find_group_chat_room(lc, addr.asStringUriOnly().c_str());
if (cr) {
L_GET_CPP_PTR_FROM_C_OBJECT(cr)->leave();
static_cast<SalReferOp *>(op)->reply(SalReasonNone);
return;
}
static_cast<SalReferOp *>(op)->reply(SalReasonDeclined);
}
static_cast<SalReferOp *>(op)->reply(SalReasonDeclined);
} else if (addr.hasParam("admin")) {
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(lc->cppCore->findChatRoom(Address(op->get_to())));
if (cr) {

View file

@ -79,8 +79,61 @@ LinphoneChatRoom *linphone_core_create_client_group_chat_room (LinphoneCore *lc,
return L_GET_C_BACK_PTR(lc->cppCore->createClientGroupChatRoom(L_C_TO_STRING(subject)));
}
void linphone_core_delete_chat_room (LinphoneCore *, LinphoneChatRoom *cr) {
LinphonePrivate::Core::deleteChatRoom(L_GET_CPP_PTR_FROM_C_OBJECT(cr));
static LinphoneChatRoom *_linphone_core_get_or_create_chat_room(LinphoneCore *lc, const char *to) {
LinphoneAddress *to_addr = linphone_core_interpret_url(lc, to);
LinphoneChatRoom *ret;
if (to_addr == NULL) {
ms_error("linphone_core_get_or_create_chat_room(): Cannot make a valid address with %s", to);
return NULL;
}
ret = _linphone_core_get_chat_room(lc, to_addr);
linphone_address_unref(to_addr);
if (!ret) {
ret = _linphone_core_create_chat_room_from_url(lc, to);
}
return ret;
}
LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAddress *addr) {
LinphoneChatRoom *ret = _linphone_core_get_chat_room(lc, addr);
if (!ret) {
ret = _linphone_core_create_chat_room(lc, addr);
}
return ret;
}
LinphoneChatRoom * linphone_core_create_client_group_chat_room(LinphoneCore *lc, const char *subject) {
const char *factoryUri = linphone_core_get_conference_factory_uri(lc);
if (!factoryUri)
return nullptr;
LinphoneChatRoom *cr = _linphone_client_group_chat_room_new(lc, factoryUri, subject);
lc->chatrooms = bctbx_list_append(lc->chatrooms, cr);
return cr;
}
LinphoneChatRoom *_linphone_core_join_client_group_chat_room (LinphoneCore *lc, const LinphonePrivate::Address &addr) {
LinphoneChatRoom *cr = _linphone_client_group_chat_room_new(lc, addr.asString().c_str(), nullptr);
L_GET_CPP_PTR_FROM_C_OBJECT(cr)->join();
lc->chatrooms = bctbx_list_append(lc->chatrooms, cr);
return cr;
}
LinphoneChatRoom *_linphone_core_create_server_group_chat_room (LinphoneCore *lc, LinphonePrivate::SalCallOp *op) {
LinphoneChatRoom *cr = _linphone_server_group_chat_room_new(lc, op);
_linphone_core_add_group_chat_room(lc, L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getConferenceAddress(), cr);
lc->chatrooms = bctbx_list_append(lc->chatrooms, cr);
return cr;
}
void linphone_core_delete_chat_room(LinphoneCore *lc, LinphoneChatRoom *cr) {
if (bctbx_list_find(lc->chatrooms, cr)) {
lc->chatrooms = bctbx_list_remove(lc->chatrooms, cr);
linphone_chat_room_delete_history(cr);
linphone_chat_room_unref(cr);
} else {
ms_error("linphone_core_delete_chat_room(): chatroom [%p] isn't part of LinphoneCore.", cr);
}
}
LinphoneChatRoom *linphone_core_get_chat_room_from_uri(LinphoneCore *lc, const char *to) {
@ -89,7 +142,8 @@ LinphoneChatRoom *linphone_core_get_chat_room_from_uri(LinphoneCore *lc, const c
int linphone_core_message_received(LinphoneCore *lc, LinphonePrivate::SalOp *op, const SalMessage *sal_msg) {
LinphoneReason reason = LinphoneReasonNotAcceptable;
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(lc->cppCore->findChatRoom(LinphonePrivate::Address(op->get_from())));
LinphoneChatRoom *cr = _linphone_core_find_group_chat_room(lc,
linphone_core_conference_server_enabled(lc) ? op->get_to() : op->get_from());
if (cr)
reason = L_GET_PRIVATE_FROM_C_OBJECT(cr)->messageReceived(op, sal_msg);
else {

View file

@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "quality_reporting.h"
#include "lime.h"
#include "conference_private.h"
#include "logger/logger.h"
#ifdef SQLITE_STORAGE_ENABLED
#include "sqlite3_bctbx_vfs.h"
@ -48,6 +49,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "mediastreamer2/msvolume.h"
#include "chat/chat-room/client-group-chat-room-p.h"
#include "chat/chat-room/server-group-chat-room-p.h"
#include "conference/remote-conference-event-handler.h"
#include "core/core.h"
@ -2137,11 +2139,25 @@ static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEve
}
}
static void _linphone_core_conference_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) {
if ((linphone_event_get_subscription_dir(lev) == LinphoneSubscriptionIncoming) && (state == LinphoneSubscriptionIncomingReceived)) {
const LinphoneAddress *resource = linphone_event_get_resource(lev);
char *resourceUri = linphone_address_as_string_uri_only(resource);
LinphoneChatRoom *cr = _linphone_core_find_group_chat_room(lc, resourceUri);
bctbx_free(resourceUri);
if (cr) {
linphone_event_accept_subscription(lev);
L_GET_PRIVATE_FROM_C_OBJECT(cr, ServerGroupChatRoom)->subscribeReceived(lev);
} else
linphone_event_deny_subscription(lev, LinphoneReasonDeclined);
}
}
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) {
_linphone_core_conference_subscription_state_changed(lc, lev, state);
}
}
@ -7146,7 +7162,84 @@ void linphone_core_set_conference_factory_uri(LinphoneCore *lc, const char *uri)
}
const char * linphone_core_get_conference_factory_uri(const LinphoneCore *lc) {
return lp_config_get_string(linphone_core_get_config(lc), "misc", "conference_factory_uri", nullptr);
return lp_config_get_string(linphone_core_get_config(lc), "misc", "conference_factory_uri", "sip:");
}
bool_t _linphone_core_has_group_chat_room(const LinphoneCore *lc, const char *id) {
bool_t result;
bctbx_iterator_t *it = bctbx_map_cchar_find_key(lc->group_chat_rooms, id);
bctbx_iterator_t *endit = bctbx_map_cchar_end(lc->group_chat_rooms);
result = !bctbx_iterator_cchar_equals(it, endit);
bctbx_iterator_cchar_delete(endit);
bctbx_iterator_cchar_delete(it);
return result;
}
void _linphone_core_add_group_chat_room(LinphoneCore *lc, const LinphonePrivate::Address &addr, LinphoneChatRoom *cr) {
Address cleanedAddr(addr);
cleanedAddr.clean();
cleanedAddr.setPort(0);
bctbx_pair_t *pair = reinterpret_cast<bctbx_pair_t *>(bctbx_pair_cchar_new(cleanedAddr.asStringUriOnly().c_str(), linphone_chat_room_ref(cr)));
bctbx_map_cchar_insert_and_delete(lc->group_chat_rooms, pair);
}
void _linphone_core_remove_group_chat_room(LinphoneCore *lc, LinphoneChatRoom *cr) {
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(cr);
Address cleanedAddr(*L_GET_CPP_PTR_FROM_C_OBJECT(confAddr));
cleanedAddr.clean();
cleanedAddr.setPort(0);
bctbx_iterator_t *it = bctbx_map_cchar_find_key(lc->group_chat_rooms, cleanedAddr.asStringUriOnly().c_str());
bctbx_iterator_t *endit = bctbx_map_cchar_end(lc->group_chat_rooms);
if (!bctbx_iterator_cchar_equals(it, endit)) {
bctbx_map_cchar_erase(lc->group_chat_rooms, it);
linphone_chat_room_unref(cr);
}
bctbx_iterator_cchar_delete(endit);
bctbx_iterator_cchar_delete(it);
}
LinphoneChatRoom *_linphone_core_find_group_chat_room(const LinphoneCore *lc, const char *id) {
LinphoneChatRoom *result = nullptr;
Address cleanedAddr(id);
cleanedAddr.clean();
cleanedAddr.setPort(0);
bctbx_iterator_t *it = bctbx_map_cchar_find_key(lc->group_chat_rooms, cleanedAddr.asStringUriOnly().c_str());
bctbx_iterator_t *endit = bctbx_map_cchar_end(lc->group_chat_rooms);
if (!bctbx_iterator_cchar_equals(it, endit)) {
result = reinterpret_cast<LinphoneChatRoom *>(bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)));
} else {
bctbx_iterator_cchar_delete(it);
Address backupAddress(cleanedAddr);
Address factoryAddress(linphone_core_get_conference_factory_uri(lc));
backupAddress.setDomain(factoryAddress.getDomain());
lWarning() << "We don't found the chat room with address " << id << " as a temporary workaround, searching with " << backupAddress.asString();
it = bctbx_map_cchar_find_key(lc->group_chat_rooms, backupAddress.asStringUriOnly().c_str());
if (!bctbx_iterator_cchar_equals(it, endit)) {
result = reinterpret_cast<LinphoneChatRoom *>(bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)));
}
if (!result) lWarning() << "Chatroom " << id << " or " << backupAddress.asString() << " not found!";
}
bctbx_iterator_cchar_delete(endit);
bctbx_iterator_cchar_delete(it);
return result;
}
void linphone_core_enable_conference_server (LinphoneCore *lc, bool_t enable) {
lp_config_set_int(linphone_core_get_config(lc), "misc", "conference_server_enabled", enable);
}
bool_t linphone_core_conference_server_enabled (const LinphoneCore *lc) {
return lp_config_get_int(linphone_core_get_config(lc), "misc", "conference_server_enabled", FALSE) ? TRUE : FALSE;
}
bool_t _linphone_core_is_conference_creation (const LinphoneCore *lc, const LinphoneAddress *addr) {
LinphoneAddress *factoryAddr = linphone_address_new(linphone_core_get_conference_factory_uri(lc));
if (!factoryAddr)
return FALSE;
bool_t result = linphone_address_weak_equal(factoryAddr, addr);
linphone_address_unref(factoryAddr);
return result;
}
void linphone_core_set_tls_cert(LinphoneCore *lc, const char *tls_cert) {

View file

@ -457,6 +457,11 @@ bool_t linphone_core_incompatible_security(LinphoneCore *lc, SalMediaDescription
extern LinphonePrivate::Sal::Callbacks linphone_sal_callbacks;
LINPHONE_PUBLIC bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc);
LINPHONE_PUBLIC bool_t linphone_core_symmetric_rtp_enabled(LinphoneCore*lc);
bool_t _linphone_core_has_group_chat_room (const LinphoneCore *lc, const char *id);
void _linphone_core_add_group_chat_room (LinphoneCore *lc, const LinphonePrivate::Address &addr, LinphoneChatRoom *cr);
void _linphone_core_remove_group_chat_room(LinphoneCore *lc, LinphoneChatRoom *cr);
bool_t _linphone_core_is_conference_creation (const LinphoneCore *lc, const LinphoneAddress *addr);
LinphoneChatRoom *_linphone_core_create_server_group_chat_room (LinphoneCore *lc, LinphonePrivate::SalCallOp *op);
void linphone_core_queue_task(LinphoneCore *lc, belle_sip_source_func_t task_fun, void *data, const char *task_description);
@ -472,6 +477,7 @@ void _linphone_proxy_config_release_ops(LinphoneProxyConfig *obj);
/*chat*/
LinphoneChatRoom * linphone_chat_room_new(LinphoneCore *core, const LinphoneAddress *addr);
LinphoneChatRoom *_linphone_client_group_chat_room_new (LinphoneCore *core, const char *uri, const char *subject);
LinphoneChatRoom *_linphone_server_group_chat_room_new (LinphoneCore *core, LinphonePrivate::SalCallOp *op);
void linphone_chat_room_release(LinphoneChatRoom *cr);
void linphone_chat_room_set_call(LinphoneChatRoom *cr, LinphoneCall *call);
bctbx_list_t * linphone_chat_room_get_transient_messages(const LinphoneChatRoom *cr);

View file

@ -4235,6 +4235,21 @@ void linphone_core_set_conference_factory_uri(LinphoneCore *lc, const char *uri)
*/
const char * linphone_core_get_conference_factory_uri(const LinphoneCore *lc);
/**
* Enable the conference server feature. This has the effect to listen of the conference factory uri
* to create new conferences when receiving INVITE messages there.
* @param[in] lc A #LinphoneCore object
* @param[in] enable A boolean value telling whether to enable or disable the conference server feature
*/
void linphone_core_enable_conference_server (LinphoneCore *lc, bool_t enable);
/**
* Tells whether the conference server feature is enabled.
* @param[in] lc A #LinphoneCore object
* @return A boolean value telling whether the conference server feature is enabled or not
*/
bool_t linphone_core_conference_server_enabled (const LinphoneCore *lc);
/**
* @}
*/

View file

@ -39,6 +39,8 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
chat/chat-room/client-group-chat-room.h
chat/chat-room/real-time-text-chat-room-p.h
chat/chat-room/real-time-text-chat-room.h
chat/chat-room/server-group-chat-room-p.h
chat/chat-room/server-group-chat-room.h
chat/cpim/cpim.h
chat/cpim/header/cpim-core-headers.h
chat/cpim/header/cpim-generic-header.h
@ -150,6 +152,7 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
chat/chat-room/chat-room.cpp
chat/chat-room/client-group-chat-room.cpp
chat/chat-room/real-time-text-chat-room.cpp
chat/chat-room/server-group-chat-room-stub.cpp
chat/cpim/header/cpim-core-headers.cpp
chat/cpim/header/cpim-generic-header.cpp
chat/cpim/header/cpim-header.cpp

View file

@ -34,6 +34,8 @@ class LINPHONE_PUBLIC Address : public ClonableObject {
friend class CallSession;
friend class ClientGroupChatRoom;
friend class ClientGroupChatRoomPrivate;
friend class ServerGroupChatRoom;
friend class ServerGroupChatRoomPrivate;
public:
explicit Address (const std::string &address = "");

View file

@ -28,8 +28,10 @@
#include "chat/chat-room/basic-chat-room.h"
#include "chat/chat-room/client-group-chat-room.h"
#include "chat/chat-room/real-time-text-chat-room-p.h"
#include "chat/chat-room/server-group-chat-room-p.h"
#include "conference/participant.h"
#include "core/core-p.h"
#include "content/content.h"
// =============================================================================
@ -352,6 +354,14 @@ LinphoneChatRoom *_linphone_client_group_chat_room_new (LinphoneCore *core, cons
return cr;
}
LinphoneChatRoom *_linphone_server_group_chat_room_new (LinphoneCore *core, LinphonePrivate::SalCallOp *op) {
LinphoneChatRoom *cr = L_INIT(ChatRoom);
L_SET_CPP_PTR_FROM_C_OBJECT(cr, LinphonePrivate::ObjectFactory::create<LinphonePrivate::ServerGroupChatRoom>(core, op));
L_GET_PRIVATE_FROM_C_OBJECT(cr)->setState(LinphonePrivate::ChatRoom::State::Instantiated);
L_GET_PRIVATE_FROM_C_OBJECT(cr, ServerGroupChatRoom)->confirmCreation();
return cr;
}
/* DEPRECATED */
void linphone_chat_room_destroy (LinphoneChatRoom *cr) {
linphone_chat_room_unref(cr);

View file

@ -51,7 +51,8 @@
F(EventLog, ConferenceNotifiedEvent) \
F(EventLog, ConferenceParticipantDeviceEvent) \
F(EventLog, ConferenceParticipantEvent) \
F(EventLog, ConferenceSubjectEvent)
F(EventLog, ConferenceSubjectEvent) \
F(ChatRoom, ServerGroupChatRoom)
// =============================================================================
// Register belle-sip ID.

View file

@ -41,6 +41,7 @@ class LINPHONE_PUBLIC ChatMessage : public Object {
friend class ChatRoomPrivate;
friend class CpimChatMessageModifier;
friend class RealTimeTextChatRoomPrivate;
friend class ServerGroupChatRoomPrivate;
public:
L_OVERRIDE_SHARED_FROM_THIS(ChatMessage);

View file

@ -441,8 +441,7 @@ void ClientGroupChatRoom::onCallSessionStateChanged (
if (state == LinphoneCallConnected) {
if (d->state == ChatRoom::State::CreationPending) {
Address addr(session->getRemoteContact());
addr.clean();
Address addr(session->getRemoteContactAddress()->asStringUriOnly());
onConferenceCreated(addr);
if (session->getRemoteContactAddress()->hasParam("isfocus"))
dConference->eventHandler->subscribe(getConferenceAddress());

View file

@ -0,0 +1,66 @@
/*
* server-group-chat-room-p.h
* Copyright (C) 2010-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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _SERVER_GROUP_CHAT_ROOM_P_H_
#define _SERVER_GROUP_CHAT_ROOM_P_H_
// From coreapi.
#include "private.h"
#include "address/address.h"
#include "chat-room-p.h"
#include "server-group-chat-room.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class Participant;
class ServerGroupChatRoomPrivate : public ChatRoomPrivate {
public:
ServerGroupChatRoomPrivate (LinphoneCore *core);
virtual ~ServerGroupChatRoomPrivate () = default;
std::shared_ptr<Participant> addParticipant (const Address &addr);
void confirmCreation ();
void confirmJoining (SalCallOp *op);
std::shared_ptr<Participant> findRemovedParticipant (const std::shared_ptr<const CallSession> &session) const;
std::string generateConferenceId () const;
void removeParticipant (const std::shared_ptr<const Participant> &participant);
void subscribeReceived (LinphoneEvent *event);
void update (SalCallOp *op);
void dispatchMessage (const Address &fromAddr, const Content &content);
void storeOrUpdateMessage (const std::shared_ptr<ChatMessage> &msg) override;
LinphoneReason messageReceived (SalOp *op, const SalMessage *msg) override;
private:
void designateAdmin ();
bool isAdminLeft () const;
private:
L_DECLARE_PUBLIC(ServerGroupChatRoom);
std::list<std::shared_ptr<Participant>> removedParticipants;
};
LINPHONE_END_NAMESPACE
#endif // ifndef _SERVER_GROUP_CHAT_ROOM_P_H_

View file

@ -0,0 +1,157 @@
/*
* server-group-chat-room.cpp
* Copyright (C) 2010-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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <algorithm>
#include "address/address-p.h"
#include "address/address.h"
#include "c-wrapper/c-wrapper.h"
#include "chat/chat-message/chat-message-p.h"
#include "chat/modifier/cpim-chat-message-modifier.h"
#include "conference/local-conference-event-handler.h"
#include "conference/local-conference-p.h"
#include "conference/participant-p.h"
#include "conference/session/call-session-p.h"
#include "content/content-type.h"
#include "logger/logger.h"
#include "sal/refer-op.h"
#include "server-group-chat-room-p.h"
// =============================================================================
using namespace std;
LINPHONE_BEGIN_NAMESPACE
ServerGroupChatRoomPrivate::ServerGroupChatRoomPrivate (LinphoneCore *core) : ChatRoomPrivate(core) {}
// -----------------------------------------------------------------------------
shared_ptr<Participant> ServerGroupChatRoomPrivate::addParticipant (const Address &addr) {
return nullptr;
}
void ServerGroupChatRoomPrivate::confirmCreation () {
}
void ServerGroupChatRoomPrivate::confirmJoining (SalCallOp *op) {
}
shared_ptr<Participant> ServerGroupChatRoomPrivate::findRemovedParticipant (const shared_ptr<const CallSession> &session) const {
return nullptr;
}
string ServerGroupChatRoomPrivate::generateConferenceId () const {
return "";
}
void ServerGroupChatRoomPrivate::removeParticipant (const shared_ptr<const Participant> &participant) {
}
void ServerGroupChatRoomPrivate::subscribeReceived (LinphoneEvent *event) {
}
void ServerGroupChatRoomPrivate::update (SalCallOp *op) {
}
// -----------------------------------------------------------------------------
void ServerGroupChatRoomPrivate::dispatchMessage (const Address &fromAddr, const Content &content) {
}
void ServerGroupChatRoomPrivate::storeOrUpdateMessage (const std::shared_ptr<ChatMessage> &msg) {
}
LinphoneReason ServerGroupChatRoomPrivate::messageReceived (SalOp *op, const SalMessage *salMsg) {
return LinphoneReasonNone;
}
// -----------------------------------------------------------------------------
void ServerGroupChatRoomPrivate::designateAdmin () {
}
bool ServerGroupChatRoomPrivate::isAdminLeft () const {
return false;
}
// =============================================================================
ServerGroupChatRoom::ServerGroupChatRoom (LinphoneCore *core, SalCallOp *op)
: ChatRoom(*new ServerGroupChatRoomPrivate(core)), LocalConference(core, Address(op->get_to()), nullptr) {
}
int ServerGroupChatRoom::getCapabilities () const {
return 0;
}
// -----------------------------------------------------------------------------
void ServerGroupChatRoom::addParticipant (const Address &addr, const CallSessionParams *params, bool hasMedia) {
}
void ServerGroupChatRoom::addParticipants (const list<Address> &addresses, const CallSessionParams *params, bool hasMedia) {
}
bool ServerGroupChatRoom::canHandleParticipants () const {
return FALSE;
}
shared_ptr<Participant> ServerGroupChatRoom::findParticipant (const Address &addr) const {
return nullptr;
}
const Address &ServerGroupChatRoom::getConferenceAddress () const {
return LocalConference::getConferenceAddress();
}
int ServerGroupChatRoom::getNbParticipants () const {
return 0;
}
list<shared_ptr<Participant>> ServerGroupChatRoom::getParticipants () const {
return LocalConference::getParticipants();
}
const string &ServerGroupChatRoom::getSubject () const {
return LocalConference::getSubject();
}
void ServerGroupChatRoom::join () {}
void ServerGroupChatRoom::leave () {}
void ServerGroupChatRoom::removeParticipant (const shared_ptr<const Participant> &participant) {
}
void ServerGroupChatRoom::removeParticipants (const list<shared_ptr<Participant>> &participants) {
}
void ServerGroupChatRoom::setParticipantAdminStatus (shared_ptr<Participant> &participant, bool isAdmin) {
}
void ServerGroupChatRoom::setSubject (const std::string &subject) {
}
// -----------------------------------------------------------------------------
void ServerGroupChatRoom::onCallSessionStateChanged (const std::shared_ptr<const CallSession> &session, LinphoneCallState state, const std::string &message) {
}
LINPHONE_END_NAMESPACE

View file

@ -0,0 +1,72 @@
/*
* server-group-chat-room.h
* Copyright (C) 2010-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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _SERVER_GROUP_CHAT_ROOM_H_
#define _SERVER_GROUP_CHAT_ROOM_H_
// From coreapi
#include "private.h"
#include "chat/chat-room/chat-room.h"
#include "conference/local-conference.h"
#include "linphone/types.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class ServerGroupChatRoomPrivate;
class ServerGroupChatRoom : public ChatRoom, public LocalConference {
public:
ServerGroupChatRoom (LinphoneCore *core, SalCallOp *op);
virtual ~ServerGroupChatRoom () = default;
int getCapabilities () const override;
public:
/* ConferenceInterface */
void addParticipant (const Address &addr, const CallSessionParams *params, bool hasMedia) override;
void addParticipants (const std::list<Address> &addresses, const CallSessionParams *params, bool hasMedia) override;
bool canHandleParticipants () const override;
std::shared_ptr<Participant> findParticipant (const Address &addr) const override;
const Address &getConferenceAddress () const override;
int getNbParticipants () const override;
std::list<std::shared_ptr<Participant>> getParticipants () const override;
const std::string &getSubject () const override;
void join () override;
void leave () override;
void removeParticipant (const std::shared_ptr<const Participant> &participant) override;
void removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
void setParticipantAdminStatus (std::shared_ptr<Participant> &participant, bool isAdmin) override;
void setSubject (const std::string &subject) override;
private:
/* CallSessionListener */
void onCallSessionStateChanged (const std::shared_ptr<const CallSession> &session, LinphoneCallState state, const std::string &message) override;
private:
L_DECLARE_PRIVATE(ServerGroupChatRoom);
L_DISABLE_COPY(ServerGroupChatRoom);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _SERVER_GROUP_CHAT_ROOM_H_

View file

@ -29,6 +29,8 @@ LINPHONE_BEGIN_NAMESPACE
class LocalConferencePrivate;
class LocalConference : public Conference {
friend class ServerGroupChatRoomPrivate;
public:
LocalConference (LinphoneCore *core, const Address &myAddress, CallListener *listener = nullptr);

View file

@ -45,6 +45,8 @@ class Participant : public Object {
friend class LocalConferenceEventHandlerPrivate;
friend class MediaSessionPrivate;
friend class RemoteConference;
friend class ServerGroupChatRoom;
friend class ServerGroupChatRoomPrivate;
public:
explicit Participant (const Address &address);

View file

@ -78,8 +78,14 @@ void RemoteConferenceEventHandler::notifyReceived (const string &xmlBody) {
tm = static_cast<time_t>(Utils::stoll(confInfo->getConferenceDescription()->getFreeText().get()));
Address cleanedConfAddress = d->confAddress;
cleanedConfAddress.clean();
cleanedConfAddress.setPort(0);
if (confInfo->getEntity() == cleanedConfAddress.asString()) {
// Temporary workaround
Address entityAddress(confInfo->getEntity().c_str());
Address cleanedConfAddress2(cleanedConfAddress);
cleanedConfAddress2.setDomain(entityAddress.getDomain());
if (confInfo->getEntity() == cleanedConfAddress.asString()
|| confInfo->getEntity() == cleanedConfAddress2.asString()) {
if (confInfo->getConferenceDescription().present() && confInfo->getConferenceDescription().get().getSubject().present())
d->listener->onSubjectChanged(tm, confInfo->getConferenceDescription().get().getSubject().get());

View file

@ -40,6 +40,8 @@ class LINPHONE_PUBLIC CallSession : public Object {
friend class ClientGroupChatRoom;
friend class ClientGroupChatRoomPrivate;
friend class Conference;
friend class ServerGroupChatRoom;
friend class ServerGroupChatRoomPrivate;
public:
L_OVERRIDE_SHARED_FROM_THIS(CallSession);

View file

@ -426,7 +426,7 @@ int SalOp::process_redirect(){
belle_sip_request_set_uri(request, redirect_uri);
redirect_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(redirect_uri)));
belle_sip_uri_set_port(redirect_uri, 0);
belle_sip_uri_set_transport_param(redirect_uri, nullptr);
belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(redirect_uri), "transport");
belle_sip_header_address_set_uri((belle_sip_header_address_t*)to, redirect_uri);
send_request(request);
return 0;