mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-21 13:08:08 +00:00
Merge fix for client group chat room
This commit is contained in:
parent
bd9af1601e
commit
64e550f764
19 changed files with 552 additions and 18 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 = "");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
66
src/chat/chat-room/server-group-chat-room-p.h
Normal file
66
src/chat/chat-room/server-group-chat-room-p.h
Normal 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_
|
||||
157
src/chat/chat-room/server-group-chat-room-stub.cpp
Normal file
157
src/chat/chat-room/server-group-chat-room-stub.cpp
Normal 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
|
||||
72
src/chat/chat-room/server-group-chat-room.h
Normal file
72
src/chat/chat-room/server-group-chat-room.h
Normal 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_
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue