c-chat-room.cpp 11.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * c-chat-room.cpp
 * Copyright (C) 2017  Belledonne Communications SARL
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "linphone/chat.h"
#include "linphone/wrapper_utils.h"
Ronan's avatar
Ronan committed
21 22

// TODO: Remove me later.
23 24 25 26 27
#include "private.h"

#include "c-wrapper/c-tools.h"
#include "chat/basic-chat-room.h"
#include "chat/chat-room-p.h"
Ronan's avatar
Ronan committed
28
#include "chat/chat-room.h"
29 30
#include "chat/client-group-chat-room.h"
#include "chat/real-time-text-chat-room-p.h"
Ronan's avatar
Ronan committed
31
#include "chat/real-time-text-chat-room.h"
32

Ronan's avatar
Ronan committed
33
// =============================================================================
34

35 36
#define GET_CPP_PTR(obj) L_GET_CPP_PTR_FROM_C_STRUCT(obj, ChatRoom)
#define GET_CPP_PRIVATE_PTR(obj) L_GET_PRIVATE_FROM_C_STRUCT(obj, ChatRoom)
37

Ronan's avatar
Ronan committed
38
using namespace std;
39

Ronan's avatar
Ronan committed
40
extern LinphoneParticipant *_linphone_participant_init ();
41

Ronan's avatar
Ronan committed
42 43
static void _linphone_chat_room_constructor (LinphoneChatRoom *cr);
static void _linphone_chat_room_destructor (LinphoneChatRoom *cr);
44 45 46

L_DECLARE_C_STRUCT_IMPL_WITH_XTORS(ChatRoom, ChatRoom, chat_room,
	_linphone_chat_room_constructor, _linphone_chat_room_destructor,
47
	LinphoneChatRoomCbs *cbs;
48 49 50
	LinphoneAddress *peerAddressCache;
)

Ronan's avatar
Ronan committed
51
static void _linphone_chat_room_constructor (LinphoneChatRoom *cr) {
52 53
	cr->cbs = linphone_chat_room_cbs_new();
}
54

Ronan's avatar
Ronan committed
55
static void _linphone_chat_room_destructor (LinphoneChatRoom *cr) {
56 57
	linphone_chat_room_cbs_unref(cr->cbs);
	cr->cbs = nullptr;
58 59 60 61 62 63
	if (cr->peerAddressCache) {
		linphone_address_unref(cr->peerAddressCache);
		cr->peerAddressCache = nullptr;
	}
}

Ronan's avatar
Ronan committed
64 65 66
// =============================================================================
// Public functions.
// =============================================================================
67

Ronan's avatar
Ronan committed
68
void linphone_chat_room_release (LinphoneChatRoom *cr) {
69 70 71
	GET_CPP_PRIVATE_PTR(cr)->release();
}

Ronan's avatar
Ronan committed
72
void linphone_chat_room_remove_transient_message (LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
73 74 75
	GET_CPP_PRIVATE_PTR(cr)->removeTransientMessage(msg);
}

Ronan's avatar
Ronan committed
76
void linphone_chat_room_send_message (LinphoneChatRoom *cr, const char *msg) {
77 78 79
	GET_CPP_PTR(cr)->sendMessage(GET_CPP_PTR(cr)->createMessage(msg));
}

Ronan's avatar
Ronan committed
80
bool_t linphone_chat_room_is_remote_composing (const LinphoneChatRoom *cr) {
81 82 83
	return GET_CPP_PTR(cr)->isRemoteComposing();
}

Ronan's avatar
Ronan committed
84
LinphoneCore *linphone_chat_room_get_lc (const LinphoneChatRoom *cr) {
85 86 87
	return linphone_chat_room_get_core(cr);
}

Ronan's avatar
Ronan committed
88
LinphoneCore *linphone_chat_room_get_core (const LinphoneChatRoom *cr) {
89 90 91
	return GET_CPP_PTR(cr)->getCore();
}

Ronan's avatar
Ronan committed
92
const LinphoneAddress *linphone_chat_room_get_peer_address (LinphoneChatRoom *cr) {
93 94 95 96 97 98 99
	if (cr->peerAddressCache) {
		linphone_address_unref(cr->peerAddressCache);
	}
	cr->peerAddressCache = linphone_address_new(GET_CPP_PTR(cr)->getPeerAddress().asString().c_str());
	return cr->peerAddressCache;
}

Ronan's avatar
Ronan committed
100
LinphoneChatMessage *linphone_chat_room_create_message (LinphoneChatRoom *cr, const char *message) {
101 102 103
	return GET_CPP_PTR(cr)->createMessage(message ? message : "");
}

Ronan's avatar
Ronan committed
104 105 106 107 108 109 110 111 112
LinphoneChatMessage *linphone_chat_room_create_message_2 (
	LinphoneChatRoom *cr,
	const char *message,
	const char *external_body_url,
	LinphoneChatMessageState state,
	time_t time,
	bool_t is_read,
	bool_t is_incoming
) {
113 114 115 116 117 118 119 120 121 122 123 124 125
	LinphoneChatMessage *msg = linphone_chat_room_create_message(cr, message);
	LinphoneCore *lc = linphone_chat_room_get_core(cr);
	msg->external_body_url = external_body_url ? ms_strdup(external_body_url) : NULL;
	msg->time = time;
	msg->is_secured = FALSE;
	linphone_chat_message_set_state(msg, state);
	if (is_incoming) {
		msg->dir = LinphoneChatMessageIncoming;
		linphone_chat_message_set_from(msg, linphone_chat_room_get_peer_address(cr));
		msg->to = linphone_address_new(linphone_core_get_identity(lc)); /*direct assignment*/
	} else {
		msg->dir = LinphoneChatMessageOutgoing;
		linphone_chat_message_set_to(msg, linphone_chat_room_get_peer_address(cr));
Ronan's avatar
Ronan committed
126
		msg->from = linphone_address_new(linphone_core_get_identity(lc)); /*direct assignment*/
127 128 129 130
	}
	return msg;
}

Ronan's avatar
Ronan committed
131 132 133 134 135 136
void linphone_chat_room_send_message2 (
	LinphoneChatRoom *cr,
	LinphoneChatMessage *msg,
	LinphoneChatMessageStateChangedCb status_cb,
	void *ud
) {
137 138 139 140 141
	msg->message_state_changed_cb = status_cb;
	msg->message_state_changed_user_data = ud;
	GET_CPP_PTR(cr)->sendMessage(msg);
}

Ronan's avatar
Ronan committed
142
void linphone_chat_room_send_chat_message_2 (LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
143 144 145 146
	linphone_chat_message_ref(msg);
	GET_CPP_PTR(cr)->sendMessage(msg);
}

Ronan's avatar
Ronan committed
147
void linphone_chat_room_send_chat_message (LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
148 149 150
	GET_CPP_PTR(cr)->sendMessage(msg);
}

Ronan's avatar
Ronan committed
151
uint32_t linphone_chat_room_get_char (const LinphoneChatRoom *cr) {
152 153 154 155 156
	if (linphone_core_realtime_text_enabled(linphone_chat_room_get_core(cr)))
		return static_cast<const LinphonePrivate::RealTimeTextChatRoom *>(GET_CPP_PTR(cr).get())->getChar();
	return 0;
}

Ronan's avatar
Ronan committed
157
void linphone_chat_room_compose (LinphoneChatRoom *cr) {
158 159 160
	GET_CPP_PTR(cr)->compose();
}

Ronan's avatar
Ronan committed
161
LinphoneCall *linphone_chat_room_get_call (const LinphoneChatRoom *cr) {
162 163 164 165 166
	if (linphone_core_realtime_text_enabled(linphone_chat_room_get_core(cr)))
		return static_cast<const LinphonePrivate::RealTimeTextChatRoom *>(GET_CPP_PTR(cr).get())->getCall();
	return nullptr;
}

Ronan's avatar
Ronan committed
167
void linphone_chat_room_set_call (LinphoneChatRoom *cr, LinphoneCall *call) {
168 169 170 171
	if (linphone_core_realtime_text_enabled(linphone_chat_room_get_core(cr)))
		static_cast<LinphonePrivate::RealTimeTextChatRoomPrivate *>(GET_CPP_PRIVATE_PTR(cr))->setCall(call);
}

Ronan's avatar
Ronan committed
172
bctbx_list_t *linphone_chat_room_get_transient_messages (const LinphoneChatRoom *cr) {
173 174 175
	return L_GET_C_LIST_FROM_CPP_LIST(GET_CPP_PRIVATE_PTR(cr)->getTransientMessages(), LinphoneChatMessage);
}

Ronan's avatar
Ronan committed
176
void linphone_chat_room_mark_as_read (LinphoneChatRoom *cr) {
177 178 179
	GET_CPP_PTR(cr)->markAsRead();
}

Ronan's avatar
Ronan committed
180
int linphone_chat_room_get_unread_messages_count (LinphoneChatRoom *cr) {
181 182 183
	return GET_CPP_PTR(cr)->getUnreadMessagesCount();
}

Ronan's avatar
Ronan committed
184
int linphone_chat_room_get_history_size (LinphoneChatRoom *cr) {
185 186 187
	return GET_CPP_PTR(cr)->getHistorySize();
}

Ronan's avatar
Ronan committed
188
void linphone_chat_room_delete_message (LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
189 190 191
	GET_CPP_PTR(cr)->deleteMessage(msg);
}

Ronan's avatar
Ronan committed
192
void linphone_chat_room_delete_history (LinphoneChatRoom *cr) {
193 194 195
	GET_CPP_PTR(cr)->deleteHistory();
}

Ronan's avatar
Ronan committed
196
bctbx_list_t *linphone_chat_room_get_history_range (LinphoneChatRoom *cr, int startm, int endm) {
197 198 199
	return L_GET_C_LIST_FROM_CPP_LIST(GET_CPP_PTR(cr)->getHistoryRange(startm, endm), LinphoneChatMessage);
}

Ronan's avatar
Ronan committed
200
bctbx_list_t *linphone_chat_room_get_history (LinphoneChatRoom *cr, int nb_message) {
201 202 203
	return L_GET_C_LIST_FROM_CPP_LIST(GET_CPP_PTR(cr)->getHistory(nb_message), LinphoneChatMessage);
}

Ronan's avatar
Ronan committed
204
LinphoneChatMessage *linphone_chat_room_find_message (LinphoneChatRoom *cr, const char *message_id) {
205 206 207
	return GET_CPP_PTR(cr)->findMessage(message_id);
}

Ronan's avatar
Ronan committed
208
LinphoneChatRoomCbs *linphone_chat_room_get_callbacks (const LinphoneChatRoom *cr) {
209 210 211
	return cr->cbs;
}

Ronan's avatar
Ronan committed
212
LinphoneParticipant *linphone_chat_room_add_participant (LinphoneChatRoom *cr, const LinphoneAddress *addr) {
213
	return L_GET_C_BACK_PTR(GET_CPP_PTR(cr)->addParticipant(
214
			*L_GET_CPP_PTR_FROM_C_STRUCT(addr, Address), nullptr, false),
215 216 217 218 219 220 221 222 223 224 225
		Participant, participant);
}

void linphone_chat_room_add_participants (LinphoneChatRoom *cr, const bctbx_list_t *addresses) {
	GET_CPP_PTR(cr)->addParticipants(L_GET_CPP_LIST_OF_CPP_OBJ_FROM_C_LIST_OF_STRUCT_PTR(addresses, Address, Address), nullptr, false);
}

bool_t linphone_chat_room_can_handle_participants (const LinphoneChatRoom *cr) {
	return GET_CPP_PTR(cr)->canHandleParticipants();
}

Ronan's avatar
Ronan committed
226
const char *linphone_chat_room_get_id (const LinphoneChatRoom *cr) {
227 228 229 230 231 232 233 234
	string id = GET_CPP_PTR(cr)->getId();
	return id.empty() ? nullptr : id.c_str();
}

int linphone_chat_room_get_nb_participants (const LinphoneChatRoom *cr) {
	return GET_CPP_PTR(cr)->getNbParticipants();
}

Ronan's avatar
Ronan committed
235
bctbx_list_t *linphone_chat_room_get_participants (const LinphoneChatRoom *cr) {
236 237 238 239
	return L_GET_C_LIST_OF_STRUCT_PTR_FROM_CPP_LIST_OF_CPP_OBJ(GET_CPP_PTR(cr)->getParticipants(), Participant, Participant, participant);
}

void linphone_chat_room_remove_participant (LinphoneChatRoom *cr, LinphoneParticipant *participant) {
240
	GET_CPP_PTR(cr)->removeParticipant(L_GET_CPP_PTR_FROM_C_STRUCT(participant, Participant));
241 242 243 244 245 246
}

void linphone_chat_room_remove_participants (LinphoneChatRoom *cr, const bctbx_list_t *participants) {
	GET_CPP_PTR(cr)->removeParticipants(L_GET_CPP_LIST_OF_CPP_OBJ_FROM_C_LIST_OF_STRUCT_PTR(participants, Participant, Participant));
}

Ronan's avatar
Ronan committed
247 248 249
// =============================================================================
// Reference and user data handling functions.
// =============================================================================
250

Ronan's avatar
Ronan committed
251
LinphoneChatRoom *linphone_chat_room_ref (LinphoneChatRoom *cr) {
252 253 254 255
	belle_sip_object_ref(cr);
	return cr;
}

Ronan's avatar
Ronan committed
256
void linphone_chat_room_unref (LinphoneChatRoom *cr) {
257 258 259
	belle_sip_object_unref(cr);
}

Ronan's avatar
Ronan committed
260
void *linphone_chat_room_get_user_data (const LinphoneChatRoom *cr) {
261
	return L_GET_USER_DATA_FROM_C_STRUCT(cr, ChatRoom);
262 263
}

Ronan's avatar
Ronan committed
264
void linphone_chat_room_set_user_data (LinphoneChatRoom *cr, void *ud) {
265
	L_SET_USER_DATA_FROM_C_STRUCT(cr, ud, ChatRoom);
266 267
}

Ronan's avatar
Ronan committed
268 269 270
// =============================================================================
// Constructor and destructor functions.
// =============================================================================
271

Ronan's avatar
Ronan committed
272
LinphoneChatRoom *linphone_chat_room_new (LinphoneCore *core, const LinphoneAddress *addr) {
273 274
	LinphoneChatRoom *cr = _linphone_chat_room_init();
	if (linphone_core_realtime_text_enabled(core))
275
		L_SET_CPP_PTR_FROM_C_STRUCT(cr, std::make_shared<LinphonePrivate::RealTimeTextChatRoom>(core, *L_GET_CPP_PTR_FROM_C_STRUCT(addr, Address)));
276
	else
277
		L_SET_CPP_PTR_FROM_C_STRUCT(cr, std::make_shared<LinphonePrivate::BasicChatRoom>(core, *L_GET_CPP_PTR_FROM_C_STRUCT(addr, Address)));
278
	linphone_core_notify_chat_room_instantiated(core, cr);
279 280
	L_GET_PRIVATE_FROM_C_STRUCT(cr, ChatRoom)->setState(LinphonePrivate::ChatRoom::State::Instantiated);
	L_GET_PRIVATE_FROM_C_STRUCT(cr, ChatRoom)->setState(LinphonePrivate::ChatRoom::State::Created);
281 282 283
	return cr;
}

Ronan's avatar
Ronan committed
284
LinphoneChatRoom *linphone_client_group_chat_room_new (LinphoneCore *core, const bctbx_list_t *addresses) {
285
	const char *factoryUri = linphone_core_get_chat_conference_factory_uri(core);
286 287 288
	if (!factoryUri)
		return nullptr;
	LinphoneAddress *factoryAddr = linphone_address_new(factoryUri);
289
	LinphoneProxyConfig *proxy = linphone_core_lookup_known_proxy(core, factoryAddr);
290 291 292
	linphone_address_unref(factoryAddr);
	std::string from;
	if (proxy)
293
		from = L_GET_CPP_PTR_FROM_C_STRUCT(linphone_proxy_config_get_identity_address(proxy), Address)->asString();
294
	if (from.empty())
295
		from = linphone_core_get_primary_contact(core);
296
	LinphonePrivate::Address me(from);
297
	std::list<LinphonePrivate::Address> l = L_GET_CPP_LIST_OF_CPP_OBJ_FROM_C_LIST_OF_STRUCT_PTR(addresses, Address, Address);
298
	LinphoneChatRoom *cr = _linphone_chat_room_init();
299 300
	L_SET_CPP_PTR_FROM_C_STRUCT(cr, make_shared<LinphonePrivate::ClientGroupChatRoom>(core, me, l));
	linphone_core_notify_chat_room_instantiated(core, cr);
301 302
	L_GET_PRIVATE_FROM_C_STRUCT(cr, ChatRoom)->setState(LinphonePrivate::ChatRoom::State::Instantiated);
	L_GET_PRIVATE_FROM_C_STRUCT(cr, ChatRoom)->setState(LinphonePrivate::ChatRoom::State::CreationPending);
303 304 305 306
	return cr;
}

/* DEPRECATED */
Ronan's avatar
Ronan committed
307
void linphone_chat_room_destroy (LinphoneChatRoom *cr) {
308 309
	linphone_chat_room_unref(cr);
}